diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-20 23:06:19 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-20 23:06:19 +0000 |
commit | 36b9a6ba9d3b3768a1862371ebe9a911ad48d5b1 (patch) | |
tree | be7491fad42db90898b9b267d43b3d35c44c2d0a /views | |
parent | 6c244119e226e5b7e4b17895b69d23bc9c0ef59a (diff) | |
download | chromium_src-36b9a6ba9d3b3768a1862371ebe9a911ad48d5b1.zip chromium_src-36b9a6ba9d3b3768a1862371ebe9a911ad48d5b1.tar.gz chromium_src-36b9a6ba9d3b3768a1862371ebe9a911ad48d5b1.tar.bz2 |
Disable the stop button when the user is hovering it and the page finishes loading, so we don't look like we stay loading forever. This change only does this for Mac and Windows, as GTK is going to be trickier.
This also fixes a pair of other bugs on Windows and Linux:
* Because we were setting the timer after telling the browser to reload, and the browser was calling us back synchronously, the timer had no effect.
* Because the timer firing changed modes with |force| set to true, if the page finished loading before the timer fired, the timer would flip the button back to reload.
BUG=46981
TEST=Hover the reload button and hit F5. When the page finishes loading, the stop button should become disabled. Mousing away should change it to an enabled reload button.
Review URL: http://codereview.chromium.org/3198005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56925 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/controls/button/custom_button.cc | 21 | ||||
-rw-r--r-- | views/controls/button/custom_button.h | 5 | ||||
-rw-r--r-- | views/widget/root_view.cc | 7 |
3 files changed, 29 insertions, 4 deletions
diff --git a/views/controls/button/custom_button.cc b/views/controls/button/custom_button.cc index 973a8e5..e87bae9 100644 --- a/views/controls/button/custom_button.cc +++ b/views/controls/button/custom_button.cc @@ -6,6 +6,7 @@ #include "app/throb_animation.h" #include "base/keyboard_codes.h" +#include "views/screen.h" namespace views { @@ -71,8 +72,13 @@ bool CustomButton::GetAccessibleState(AccessibilityTypes::State* state) { } void CustomButton::SetEnabled(bool enabled) { - if (enabled ? (state_ == BS_DISABLED) : (state_ != BS_DISABLED)) - SetState(enabled ? BS_NORMAL : BS_DISABLED); + if (enabled ? (state_ != BS_DISABLED) : (state_ == BS_DISABLED)) + return; + + if (enabled) + SetState(IsMouseHovered() ? BS_HOT : BS_NORMAL); + else + SetState(BS_DISABLED); } bool CustomButton::IsEnabled() const { @@ -83,6 +89,17 @@ bool CustomButton::IsFocusable() const { return (state_ != BS_DISABLED) && View::IsFocusable(); } +bool CustomButton::IsMouseHovered() const { + // If we haven't yet been placed in an onscreen view hierarchy, we can't be + // hovered. + if (!GetWidget()) + return false; + + gfx::Point cursor_pos(Screen::GetCursorScreenPoint()); + ConvertPointToView(NULL, this, &cursor_pos); + return HitTest(cursor_pos); +} + //////////////////////////////////////////////////////////////////////////////// // CustomButton, protected: diff --git a/views/controls/button/custom_button.h b/views/controls/button/custom_button.h index 1f85e0b..4d7dff7 100644 --- a/views/controls/button/custom_button.h +++ b/views/controls/button/custom_button.h @@ -63,6 +63,11 @@ class CustomButton : public Button, } bool request_focus_on_press() const { return request_focus_on_press_; } + // Returns true if the mouse pointer is over this control. Note that this + // isn't the same as IsHotTracked() because the mouse may be over the control + // when it's disabled. + bool IsMouseHovered() const; + protected: // Construct the Button with a Listener. See comment for Button's ctor. explicit CustomButton(ButtonListener* listener); diff --git a/views/widget/root_view.cc b/views/widget/root_view.cc index 91ba511..a56ec99 100644 --- a/views/widget/root_view.cc +++ b/views/widget/root_view.cc @@ -455,8 +455,11 @@ void RootView::OnMouseReleased(const MouseEvent& e, bool canceled) { void RootView::OnMouseMoved(const MouseEvent& e) { View* v = GetViewForPoint(e.location()); - // Find the first enabled view. - while (v && !v->IsEnabled()) + // Find the first enabled view, or the existing move handler, whichever comes + // first. The check for the existing handler is because if a view becomes + // disabled while handling moves, it's wrong to suddenly send ET_MOUSE_EXITED + // and ET_MOUSE_ENTERED events, because the mouse hasn't actually exited yet. + while (v && !v->IsEnabled() && (v != mouse_move_handler_)) v = v->GetParent(); if (v && v != this) { if (v != mouse_move_handler_) { |