diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 17:17:51 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-26 17:17:51 +0000 |
commit | ee8f30e6d53fc657305af0bd074066f5bca1b63c (patch) | |
tree | 0a1779ae5d1bd83421d4cf0ccd55a09dff0a83df /views | |
parent | 45313cb9ff691d9e13d9cbb51d4128e12ad548cc (diff) | |
download | chromium_src-ee8f30e6d53fc657305af0bd074066f5bca1b63c.zip chromium_src-ee8f30e6d53fc657305af0bd074066f5bca1b63c.tar.gz chromium_src-ee8f30e6d53fc657305af0bd074066f5bca1b63c.tar.bz2 |
Makes the download shelf auto-close after the user opens all downloads
and moves mouse off the shelf.
BUG=27797
TEST=on windows download an item, open it, move the mouse off the
download shelf and make sure it closes.
Review URL: http://codereview.chromium.org/3177034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57541 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r-- | views/mouse_watcher.cc | 34 | ||||
-rw-r--r-- | views/mouse_watcher.h | 9 |
2 files changed, 32 insertions, 11 deletions
diff --git a/views/mouse_watcher.cc b/views/mouse_watcher.cc index dfe8d60..033a6f6b 100644 --- a/views/mouse_watcher.cc +++ b/views/mouse_watcher.cc @@ -9,6 +9,7 @@ #include "base/task.h" #include "views/screen.h" #include "views/view.h" +#include "views/window/window.h" namespace views { @@ -47,9 +48,11 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer { // switch (msg.message) { case WM_MOUSEMOVE: + HandleGlobalMouseMoveEvent(false); + break; case WM_MOUSELEAVE: case WM_NCMOUSELEAVE: - HandleGlobalMouseMoveEvent(); + HandleGlobalMouseMoveEvent(true); break; } } @@ -60,8 +63,10 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer { void DidProcessEvent(GdkEvent* event) { switch (event->type) { case GDK_MOTION_NOTIFY: + HandleGlobalMouseMoveEvent(false); + break; case GDK_LEAVE_NOTIFY: - HandleGlobalMouseMoveEvent(); + HandleGlobalMouseMoveEvent(true); break; default: break; @@ -70,28 +75,35 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer { #endif private: - views::View* view() { return mouse_watcher_->host_; } + View* view() const { return mouse_watcher_->host_; } // Returns whether or not the cursor is currently in the view's "zone" which // is defined as a slightly larger region than the view. bool IsCursorInViewZone() { gfx::Rect bounds = view()->GetLocalBounds(true); gfx::Point view_topleft(bounds.origin()); - views::View::ConvertPointToScreen(view(), &view_topleft); + View::ConvertPointToScreen(view(), &view_topleft); bounds.set_origin(view_topleft); bounds.SetRect(view_topleft.x() - mouse_watcher_->hot_zone_insets_.left(), view_topleft.y() - mouse_watcher_->hot_zone_insets_.top(), bounds.width() + mouse_watcher_->hot_zone_insets_.width(), bounds.height() + mouse_watcher_->hot_zone_insets_.height()); - gfx::Point cursor_point = views::Screen::GetCursorScreenPoint(); + gfx::Point cursor_point = Screen::GetCursorScreenPoint(); return bounds.Contains(cursor_point.x(), cursor_point.y()); } + // Returns true if the mouse is over the view's window. + bool IsMouseOverWindow() { + return Screen::GetWindowAtCursorScreenPoint() == + view()->GetWindow()->GetNativeWindow(); + } + // Called from the message loop observer when a mouse movement has occurred. - void HandleGlobalMouseMoveEvent() { - if (!IsCursorInViewZone()) { + void HandleGlobalMouseMoveEvent(bool check_window) { + bool in_view = IsCursorInViewZone(); + if (!in_view || (check_window && !IsMouseOverWindow())) { // Mouse moved outside the view's zone, start a timer to notify the // listener. if (notify_listener_factory_.empty()) { @@ -99,7 +111,8 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer { FROM_HERE, notify_listener_factory_.NewRunnableMethod( &Observer::NotifyListener), - kNotifyListenerTimeMs); + !in_view ? kNotifyListenerTimeMs : + mouse_watcher_->notify_on_exit_time_ms_); } } else { // Mouse moved quickly out of the view and then into it again, so cancel @@ -125,12 +138,13 @@ class MouseWatcher::Observer : public MessageLoopForUI::Observer { MouseWatcherListener::~MouseWatcherListener() { } -MouseWatcher::MouseWatcher(views::View* host, +MouseWatcher::MouseWatcher(View* host, MouseWatcherListener* listener, const gfx::Insets& hot_zone_insets) : host_(host), listener_(listener), - hot_zone_insets_(hot_zone_insets) { + hot_zone_insets_(hot_zone_insets), + notify_on_exit_time_ms_(kNotifyListenerTimeMs) { } MouseWatcher::~MouseWatcher() { diff --git a/views/mouse_watcher.h b/views/mouse_watcher.h index 7037487..d23483d 100644 --- a/views/mouse_watcher.h +++ b/views/mouse_watcher.h @@ -37,6 +37,10 @@ class MouseWatcher { const gfx::Insets& hot_zone_insets); ~MouseWatcher(); + // Sets the amount to delay before notifying the listener when the mouse exits + // the view by way of going to another window. + void set_notify_on_exit_time_ms(int time) { notify_on_exit_time_ms_ = time; } + // Starts watching mouse movements. When the mouse moves outside the bounds of // the view the listener is notified. |Start| may be invoked any number of // times. If the mouse moves outside the bounds of the view the listener is @@ -56,7 +60,7 @@ class MouseWatcher { void NotifyListener(); // View we're listening for events over. - views::View* host_; + View* host_; // Our listener. MouseWatcherListener* listener_; @@ -67,6 +71,9 @@ class MouseWatcher { // Does the actual work of listening for mouse events. scoped_ptr<Observer> observer_; + // See description above setter. + int notify_on_exit_time_ms_; + DISALLOW_COPY_AND_ASSIGN(MouseWatcher); }; |