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

Side by Side Diff: ui/views/mouse_watcher.cc

Issue 60443003: Makes MouseWatcher work while in metro mode (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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
« no previous file with comments | « no previous file | ui/views/views.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/mouse_watcher.h" 5 #include "ui/views/mouse_watcher.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/event_types.h" 9 #include "base/event_types.h"
10 #include "base/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "ui/events/event_constants.h" 12 #include "ui/events/event_constants.h"
13 #include "ui/events/event_utils.h" 13 #include "ui/events/event_utils.h"
14 #include "ui/gfx/screen.h" 14 #include "ui/gfx/screen.h"
15 15
16 #if defined(USE_AURA)
17 #include "ui/aura/env.h"
18 #include "ui/aura/window.h"
19 #include "ui/events/event.h"
20 #include "ui/events/event_handler.h"
21 #endif
22
16 namespace views { 23 namespace views {
17 24
18 // Amount of time between when the mouse moves outside the Host's zone and when 25 // Amount of time between when the mouse moves outside the Host's zone and when
19 // the listener is notified. 26 // the listener is notified.
20 const int kNotifyListenerTimeMs = 300; 27 const int kNotifyListenerTimeMs = 300;
21 28
29 #if defined(OS_WIN) && !defined(USE_AURA)
sky 2013/11/05 18:52:56 I'm going with totally different ifdefs since hope
22 class MouseWatcher::Observer : public base::MessageLoopForUI::Observer { 30 class MouseWatcher::Observer : public base::MessageLoopForUI::Observer {
23 public: 31 public:
24 explicit Observer(MouseWatcher* mouse_watcher) 32 explicit Observer(MouseWatcher* mouse_watcher)
25 : mouse_watcher_(mouse_watcher), 33 : mouse_watcher_(mouse_watcher),
26 notify_listener_factory_(this) { 34 notify_listener_factory_(this) {
27 base::MessageLoopForUI::current()->AddObserver(this); 35 base::MessageLoopForUI::current()->AddObserver(this);
28 } 36 }
29 37
30 virtual ~Observer() { 38 virtual ~Observer() {
31 base::MessageLoopForUI::current()->RemoveObserver(this); 39 base::MessageLoopForUI::current()->RemoveObserver(this);
32 } 40 }
33 41
34 // MessageLoop::Observer implementation: 42 // MessageLoop::Observer implementation:
35 #if defined(OS_WIN)
36 virtual base::EventStatus WillProcessEvent( 43 virtual base::EventStatus WillProcessEvent(
37 const base::NativeEvent& event) OVERRIDE { 44 const base::NativeEvent& event) OVERRIDE {
38 return base::EVENT_CONTINUE; 45 return base::EVENT_CONTINUE;
39 } 46 }
40 47
41 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE { 48 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
42 // We spy on three different Windows messages here to see if the mouse has 49 // We spy on three different Windows messages here to see if the mouse has
43 // moved out of the bounds of the current view. The messages are: 50 // moved out of the bounds of the current view. The messages are:
44 // 51 //
45 // WM_MOUSEMOVE: 52 // WM_MOUSEMOVE:
46 // For when the mouse moves from the view into the rest of the browser UI, 53 // For when the mouse moves from the view into the rest of the browser UI,
47 // i.e. within the bounds of the same windows HWND. 54 // i.e. within the bounds of the same windows HWND.
48 // WM_MOUSELEAVE: 55 // WM_MOUSELEAVE:
49 // For when the mouse moves out of the bounds of the view's HWND. 56 // For when the mouse moves out of the bounds of the view's HWND.
50 // WM_NCMOUSELEAVE: 57 // WM_NCMOUSELEAVE:
51 // For notification when the mouse leaves the _non-client_ area. 58 // For notification when the mouse leaves the _non-client_ area.
52 // 59 //
53 switch (event.message) { 60 switch (event.message) {
54 case WM_MOUSEMOVE: 61 case WM_MOUSEMOVE:
55 HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_MOVE); 62 HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_MOVE);
56 break; 63 break;
57 case WM_MOUSELEAVE: 64 case WM_MOUSELEAVE:
58 case WM_NCMOUSELEAVE: 65 case WM_NCMOUSELEAVE:
59 HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_EXIT); 66 HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_EXIT);
60 break; 67 break;
61 } 68 }
62 } 69 }
63 #elif defined(USE_AURA)
64 virtual base::EventStatus WillProcessEvent(
65 const base::NativeEvent& event) OVERRIDE {
66 return base::EVENT_CONTINUE;
67 }
68 virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE {
69 switch (ui::EventTypeFromNative(event)) {
70 case ui::ET_MOUSE_MOVED:
71 case ui::ET_MOUSE_DRAGGED:
72 // DRAGGED is a special case of MOVED. See events_win.cc/events_x.cc.
73 HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_MOVE);
74 break;
75 case ui::ET_MOUSE_EXITED:
76 HandleGlobalMouseMoveEvent(MouseWatcherHost::MOUSE_EXIT);
77 break;
78 default:
79 break;
80 }
81 }
82 #endif
83 70
84 private: 71 private:
85 MouseWatcherHost* host() const { return mouse_watcher_->host_.get(); } 72 MouseWatcherHost* host() const { return mouse_watcher_->host_.get(); }
86 73
87 // Called from the message loop observer when a mouse movement has occurred. 74 // Called from the message loop observer when a mouse movement has occurred.
88 void HandleGlobalMouseMoveEvent(MouseWatcherHost::MouseEventType event_type) { 75 void HandleGlobalMouseMoveEvent(MouseWatcherHost::MouseEventType event_type) {
89 bool contained = host()->Contains( 76 bool contained = host()->Contains(
90 // TODO(scottmg): Native is wrong http://crbug.com/133312 77 // TODO(scottmg): Native is wrong http://crbug.com/133312
91 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(), 78 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint(),
92 event_type); 79 event_type);
93 if (!contained) { 80 if (!contained) {
94 // Mouse moved outside the host's zone, start a timer to notify the 81 // Mouse moved outside the host's zone, start a timer to notify the
95 // listener. 82 // listener.
96 if (!notify_listener_factory_.HasWeakPtrs()) { 83 if (!notify_listener_factory_.HasWeakPtrs()) {
84 base::MessageLoop::current()->PostDelayedTask(
85 FROM_HERE,
86 base::Bind(&Observer::NotifyListener,
87 notify_listener_factory_.GetWeakPtr()),
88 event_type == MouseWatcherHost::MOUSE_MOVE
89 ? base::TimeDelta::FromMilliseconds(kNotifyListenerTimeMs)
90 : mouse_watcher_->notify_on_exit_time_);
91 }
92 } else {
93 // Mouse moved quickly out of the host and then into it again, so cancel
94 // the timer.
95 notify_listener_factory_.InvalidateWeakPtrs();
96 }
97 }
98
99 void NotifyListener() {
100 mouse_watcher_->NotifyListener();
101 // WARNING: we've been deleted.
102 }
103
104 private:
105 MouseWatcher* mouse_watcher_;
106
107 // A factory that is used to construct a delayed callback to the listener.
108 base::WeakPtrFactory<Observer> notify_listener_factory_;
109
110 DISALLOW_COPY_AND_ASSIGN(Observer);
111 };
112 #else
113 class MouseWatcher::Observer : public ui::EventHandler {
114 public:
115 explicit Observer(MouseWatcher* mouse_watcher)
116 : mouse_watcher_(mouse_watcher),
117 notify_listener_factory_(this) {
118 aura::Env::GetInstance()->AddPreTargetHandler(this);
119 }
120
121 virtual ~Observer() {
122 aura::Env::GetInstance()->RemovePreTargetHandler(this);
123 }
124
125 // ui::EventHandler implementation:
126 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
127 switch (event->type()) {
128 case ui::ET_MOUSE_MOVED:
129 case ui::ET_MOUSE_DRAGGED:
130 HandleMouseEvent(MouseWatcherHost::MOUSE_MOVE);
131 break;
132 case ui::ET_MOUSE_EXITED:
133 HandleMouseEvent(MouseWatcherHost::MOUSE_EXIT);
134 break;
135 default:
136 break;
137 }
138 }
139
140 private:
141 MouseWatcherHost* host() const { return mouse_watcher_->host_.get(); }
142
143 // Called when a mouse event we're interested is seen.
144 void HandleMouseEvent(MouseWatcherHost::MouseEventType event_type) {
145 // It's safe to use last_mouse_location() here as this function is invoked
146 // during event dispatching.
147 if (!host()->Contains(aura::Env::GetInstance()->last_mouse_location(),
148 event_type)) {
149 // Mouse moved outside the host's zone, start a timer to notify the
150 // listener.
151 if (!notify_listener_factory_.HasWeakPtrs()) {
97 base::MessageLoop::current()->PostDelayedTask( 152 base::MessageLoop::current()->PostDelayedTask(
98 FROM_HERE, 153 FROM_HERE,
99 base::Bind(&Observer::NotifyListener, 154 base::Bind(&Observer::NotifyListener,
100 notify_listener_factory_.GetWeakPtr()), 155 notify_listener_factory_.GetWeakPtr()),
101 event_type == MouseWatcherHost::MOUSE_MOVE 156 event_type == MouseWatcherHost::MOUSE_MOVE
102 ? base::TimeDelta::FromMilliseconds(kNotifyListenerTimeMs) 157 ? base::TimeDelta::FromMilliseconds(kNotifyListenerTimeMs)
103 : mouse_watcher_->notify_on_exit_time_); 158 : mouse_watcher_->notify_on_exit_time_);
104 } 159 }
105 } else { 160 } else {
106 // Mouse moved quickly out of the host and then into it again, so cancel 161 // Mouse moved quickly out of the host and then into it again, so cancel
107 // the timer. 162 // the timer.
108 notify_listener_factory_.InvalidateWeakPtrs(); 163 notify_listener_factory_.InvalidateWeakPtrs();
109 } 164 }
110 } 165 }
111 166
112 void NotifyListener() { 167 void NotifyListener() {
113 mouse_watcher_->NotifyListener(); 168 mouse_watcher_->NotifyListener();
114 // WARNING: we've been deleted. 169 // WARNING: we've been deleted.
115 } 170 }
116 171
117 private: 172 private:
118 MouseWatcher* mouse_watcher_; 173 MouseWatcher* mouse_watcher_;
119 174
120 // A factory that is used to construct a delayed callback to the listener. 175 // A factory that is used to construct a delayed callback to the listener.
121 base::WeakPtrFactory<Observer> notify_listener_factory_; 176 base::WeakPtrFactory<Observer> notify_listener_factory_;
122 177
123 DISALLOW_COPY_AND_ASSIGN(Observer); 178 DISALLOW_COPY_AND_ASSIGN(Observer);
124 }; 179 };
180 #endif
125 181
126 MouseWatcherListener::~MouseWatcherListener() { 182 MouseWatcherListener::~MouseWatcherListener() {
127 } 183 }
128 184
129 MouseWatcherHost::~MouseWatcherHost() { 185 MouseWatcherHost::~MouseWatcherHost() {
130 } 186 }
131 187
132 MouseWatcher::MouseWatcher(MouseWatcherHost* host, 188 MouseWatcher::MouseWatcher(MouseWatcherHost* host,
133 MouseWatcherListener* listener) 189 MouseWatcherListener* listener)
134 : host_(host), 190 : host_(host),
(...skipping 13 matching lines...) Expand all
148 void MouseWatcher::Stop() { 204 void MouseWatcher::Stop() {
149 observer_.reset(NULL); 205 observer_.reset(NULL);
150 } 206 }
151 207
152 void MouseWatcher::NotifyListener() { 208 void MouseWatcher::NotifyListener() {
153 observer_.reset(NULL); 209 observer_.reset(NULL);
154 listener_->MouseMovedOutOfHost(); 210 listener_->MouseMovedOutOfHost();
155 } 211 }
156 212
157 } // namespace views 213 } // namespace views
OLDNEW
« no previous file with comments | « no previous file | ui/views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698