Index: views/mouse_watcher.cc |
diff --git a/views/mouse_watcher.cc b/views/mouse_watcher.cc |
index dfe8d60993ded919404f5df6a3431b39d005ad02..1d973f18173d357308767ddedab602a3685946ba 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() { return mouse_watcher_->host_; } |
Jay Civelli
2010/08/26 16:10:32
Make it const.
|
// 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() { |