Index: ui/views/controls/button/menu_button.cc |
diff --git a/ui/views/controls/button/menu_button.cc b/ui/views/controls/button/menu_button.cc |
index b07cd81774c270fffc4be3604c59a7b3673b4c07..9b2adb93bae0564594ea1494fd1b1f0e8cb5a716 100644 |
--- a/ui/views/controls/button/menu_button.cc |
+++ b/ui/views/controls/button/menu_button.cc |
@@ -48,7 +48,7 @@ MenuButton::MenuButton(ButtonListener* listener, |
MenuButtonListener* menu_button_listener, |
bool show_menu_marker) |
: LabelButton(listener, text), |
- menu_visible_(false), |
+ menus_visible_(0), |
menu_offset_(kDefaultMenuOffsetX, kDefaultMenuOffsetY), |
listener_(menu_button_listener), |
show_menu_marker_(show_menu_marker), |
@@ -69,8 +69,34 @@ MenuButton::~MenuButton() { |
// |
//////////////////////////////////////////////////////////////////////////////// |
+void MenuButton::AttachMenu() { |
+ DCHECK_GE(menus_visible_, 0); |
+ ++menus_visible_; |
+ SetState(STATE_PRESSED); |
+} |
+ |
+void MenuButton::DetachMenu() { |
+ --menus_visible_; |
+ DCHECK_GE(menus_visible_, 0); |
+ // If this was the last menu, we need to reset the state manually since we |
+ // don't respond to mouse movement while menus are visible. |
+ if (menus_visible_ == 0) { |
+ // We set "normal" and not "hot" because the likelihood is that the mouse is |
+ // now somewhere else (user clicked elsewhere on screen to close the menu |
+ // or selected an item) and we will inevitably refresh the hot state |
+ // in the event the mouse _is_ over the view. |
+ SetState(STATE_NORMAL); |
+ } |
+} |
+ |
bool MenuButton::Activate() { |
SetState(STATE_PRESSED); |
+ |
+ // We're already showing a menu (even if it might not be the main menu for |
+ // this button). Don't show another one. |
+ if (menu_visible()) |
+ return false; |
+ |
if (listener_) { |
gfx::Rect lb = GetLocalBounds(); |
@@ -100,7 +126,7 @@ bool MenuButton::Activate() { |
static_cast<internal::RootView*>(GetWidget()->GetRootView())-> |
SetMouseHandler(NULL); |
- menu_visible_ = true; |
+ AttachMenu(); |
bool destroyed = false; |
destroyed_flag_ = &destroyed; |
@@ -114,18 +140,9 @@ bool MenuButton::Activate() { |
destroyed_flag_ = NULL; |
- menu_visible_ = false; |
+ DetachMenu(); |
menu_closed_time_ = TimeTicks::Now(); |
- // Now that the menu has closed, we need to manually reset state to |
- // "normal" since the menu modal loop will have prevented normal |
- // mouse move messages from getting to this View. We set "normal" |
- // and not "hot" because the likelihood is that the mouse is now |
- // somewhere else (user clicked elsewhere on screen to close the menu |
- // or selected an item) and we will inevitably refresh the hot state |
- // in the event the mouse _is_ over the view. |
- SetState(STATE_NORMAL); |
- |
// We must return false here so that the RootView does not get stuck |
// sending all mouse pressed events to us instead of the appropriate |
// target. |
@@ -191,15 +208,10 @@ void MenuButton::OnMouseReleased(const ui::MouseEvent& event) { |
} |
} |
-// The reason we override View::OnMouseExited is because we get this event when |
-// we display the menu. If we don't override this method then |
-// BaseButton::OnMouseExited will get the event and will set the button's state |
-// to STATE_NORMAL instead of keeping the state BM_PUSHED. This, in turn, will |
-// cause the button to appear depressed while the menu is displayed. |
-void MenuButton::OnMouseExited(const ui::MouseEvent& event) { |
- if ((state_ != STATE_DISABLED) && (!menu_visible_) && (!InDrag())) { |
- SetState(STATE_NORMAL); |
- } |
+bool MenuButton::ShouldRespondToMouseMovement() { |
+ // We should ignore mouse events while a menu is showing so the proper state |
+ // (usually STATE_PRESSED) remains. |
+ return menus_visible_ == 0; |
} |
void MenuButton::OnGestureEvent(ui::GestureEvent* event) { |