OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/base/test/ui_controls.h" | 5 #include "ui/base/test/ui_controls.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #import "base/mac/foundation_util.h" | 12 #import "base/mac/foundation_util.h" |
13 #import "base/mac/scoped_objc_class_swizzler.h" | 13 #import "base/mac/scoped_objc_class_swizzler.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" |
15 #include "ui/base/cocoa/cocoa_base_utils.h" | 16 #include "ui/base/cocoa/cocoa_base_utils.h" |
16 #include "ui/events/keycodes/keyboard_code_conversion_mac.h" | 17 #include "ui/events/keycodes/keyboard_code_conversion_mac.h" |
17 #import "ui/events/test/cocoa_test_event_utils.h" | 18 #import "ui/events/test/cocoa_test_event_utils.h" |
18 #include "ui/gfx/geometry/point.h" | 19 #include "ui/gfx/geometry/point.h" |
19 #import "ui/gfx/mac/coordinate_conversion.h" | 20 #import "ui/gfx/mac/coordinate_conversion.h" |
20 | 21 |
21 // Implementation details: We use [NSApplication sendEvent:] instead | 22 // Implementation details: We use [NSApplication sendEvent:] instead |
22 // of [NSApplication postEvent:atStart:] so that the event gets sent | 23 // of [NSApplication postEvent:atStart:] so that the event gets sent |
23 // immediately. This lets us run the post-event task right | 24 // immediately. This lets us run the post-event task right |
24 // immediately as well. Unfortunately I cannot subclass NSEvent (it's | 25 // immediately as well. Unfortunately I cannot subclass NSEvent (it's |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 | 133 |
133 // A helper function to watch for the event queue. The specific task will be | 134 // A helper function to watch for the event queue. The specific task will be |
134 // fired when there is no more event in the queue. | 135 // fired when there is no more event in the queue. |
135 void EventQueueWatcher(const base::Closure& task) { | 136 void EventQueueWatcher(const base::Closure& task) { |
136 NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask | 137 NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask |
137 untilDate:nil | 138 untilDate:nil |
138 inMode:NSDefaultRunLoopMode | 139 inMode:NSDefaultRunLoopMode |
139 dequeue:NO]; | 140 dequeue:NO]; |
140 // If there is still event in the queue, then we need to check again. | 141 // If there is still event in the queue, then we need to check again. |
141 if (event) { | 142 if (event) { |
142 base::MessageLoop::current()->PostTask( | 143 base::ThreadTaskRunnerHandle::Get()->PostTask( |
143 FROM_HERE, | 144 FROM_HERE, base::Bind(&EventQueueWatcher, task)); |
144 base::Bind(&EventQueueWatcher, task)); | |
145 } else { | 145 } else { |
146 base::MessageLoop::current()->PostTask(FROM_HERE, task); | 146 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); |
147 } | 147 } |
148 } | 148 } |
149 | 149 |
150 // Returns the NSWindow located at |g_mouse_location|. NULL if there is no | 150 // Returns the NSWindow located at |g_mouse_location|. NULL if there is no |
151 // window there, or if the window located there is not owned by the application. | 151 // window there, or if the window located there is not owned by the application. |
152 // On Mac, unless dragging, mouse events are sent to the window under the | 152 // On Mac, unless dragging, mouse events are sent to the window under the |
153 // cursor. Note that the OS will ignore transparent windows and windows that | 153 // cursor. Note that the OS will ignore transparent windows and windows that |
154 // explicitly ignore mouse events. | 154 // explicitly ignore mouse events. |
155 NSWindow* WindowAtCurrentMouseLocation() { | 155 NSWindow* WindowAtCurrentMouseLocation() { |
156 NSInteger window_number = [NSWindow windowNumberAtPoint:g_mouse_location | 156 NSInteger window_number = [NSWindow windowNumberAtPoint:g_mouse_location |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 // TODO(suzhe): Using [NSApplication postEvent:atStart:] here causes | 275 // TODO(suzhe): Using [NSApplication postEvent:atStart:] here causes |
276 // BrowserKeyEventsTest.CommandKeyEvents to fail. See http://crbug.com/49270 | 276 // BrowserKeyEventsTest.CommandKeyEvents to fail. See http://crbug.com/49270 |
277 // But using [NSApplication sendEvent:] should be safe for keyboard events, | 277 // But using [NSApplication sendEvent:] should be safe for keyboard events, |
278 // because until now, no code wants to retrieve the next event when handling | 278 // because until now, no code wants to retrieve the next event when handling |
279 // a keyboard event. | 279 // a keyboard event. |
280 for (std::vector<NSEvent*>::iterator iter = events.begin(); | 280 for (std::vector<NSEvent*>::iterator iter = events.begin(); |
281 iter != events.end(); ++iter) | 281 iter != events.end(); ++iter) |
282 [[NSApplication sharedApplication] sendEvent:*iter]; | 282 [[NSApplication sharedApplication] sendEvent:*iter]; |
283 | 283 |
284 if (!task.is_null()) { | 284 if (!task.is_null()) { |
285 base::MessageLoop::current()->PostTask( | 285 base::ThreadTaskRunnerHandle::Get()->PostTask( |
286 FROM_HERE, base::Bind(&EventQueueWatcher, task)); | 286 FROM_HERE, base::Bind(&EventQueueWatcher, task)); |
287 } | 287 } |
288 | 288 |
289 return true; | 289 return true; |
290 } | 290 } |
291 | 291 |
292 bool SendMouseMove(long x, long y) { | 292 bool SendMouseMove(long x, long y) { |
293 CHECK(g_ui_controls_enabled); | 293 CHECK(g_ui_controls_enabled); |
294 return SendMouseMoveNotifyWhenDone(x, y, base::Closure()); | 294 return SendMouseMoveNotifyWhenDone(x, y, base::Closure()); |
295 } | 295 } |
(...skipping 28 matching lines...) Expand all Loading... |
324 modifierFlags:0 | 324 modifierFlags:0 |
325 timestamp:timestamp | 325 timestamp:timestamp |
326 windowNumber:[window windowNumber] | 326 windowNumber:[window windowNumber] |
327 context:nil | 327 context:nil |
328 eventNumber:0 | 328 eventNumber:0 |
329 clickCount:event_type == NSMouseMoved ? 0 : 1 | 329 clickCount:event_type == NSMouseMoved ? 0 : 1 |
330 pressure:event_type == NSMouseMoved ? 0.0 : 1.0]; | 330 pressure:event_type == NSMouseMoved ? 0.0 : 1.0]; |
331 [[NSApplication sharedApplication] postEvent:event atStart:NO]; | 331 [[NSApplication sharedApplication] postEvent:event atStart:NO]; |
332 | 332 |
333 if (!task.is_null()) { | 333 if (!task.is_null()) { |
334 base::MessageLoop::current()->PostTask( | 334 base::ThreadTaskRunnerHandle::Get()->PostTask( |
335 FROM_HERE, base::Bind(&EventQueueWatcher, task)); | 335 FROM_HERE, base::Bind(&EventQueueWatcher, task)); |
336 } | 336 } |
337 | 337 |
338 return true; | 338 return true; |
339 } | 339 } |
340 | 340 |
341 bool SendMouseEvents(MouseButton type, int state) { | 341 bool SendMouseEvents(MouseButton type, int state) { |
342 CHECK(g_ui_controls_enabled); | 342 CHECK(g_ui_controls_enabled); |
343 return SendMouseEventsNotifyWhenDone(type, state, base::Closure()); | 343 return SendMouseEventsNotifyWhenDone(type, state, base::Closure()); |
344 } | 344 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 modifierFlags:0 | 388 modifierFlags:0 |
389 timestamp:TimeIntervalSinceSystemStartup() | 389 timestamp:TimeIntervalSinceSystemStartup() |
390 windowNumber:[window windowNumber] | 390 windowNumber:[window windowNumber] |
391 context:nil | 391 context:nil |
392 eventNumber:0 | 392 eventNumber:0 |
393 clickCount:1 | 393 clickCount:1 |
394 pressure:state == DOWN ? 1.0 : 0.0]; | 394 pressure:state == DOWN ? 1.0 : 0.0]; |
395 [[NSApplication sharedApplication] postEvent:event atStart:NO]; | 395 [[NSApplication sharedApplication] postEvent:event atStart:NO]; |
396 | 396 |
397 if (!task.is_null()) { | 397 if (!task.is_null()) { |
398 base::MessageLoop::current()->PostTask( | 398 base::ThreadTaskRunnerHandle::Get()->PostTask( |
399 FROM_HERE, base::Bind(&EventQueueWatcher, task)); | 399 FROM_HERE, base::Bind(&EventQueueWatcher, task)); |
400 } | 400 } |
401 | 401 |
402 return true; | 402 return true; |
403 } | 403 } |
404 | 404 |
405 bool SendMouseClick(MouseButton type) { | 405 bool SendMouseClick(MouseButton type) { |
406 CHECK(g_ui_controls_enabled); | 406 CHECK(g_ui_controls_enabled); |
407 return SendMouseEventsNotifyWhenDone(type, UP|DOWN, base::Closure()); | 407 return SendMouseEventsNotifyWhenDone(type, UP|DOWN, base::Closure()); |
408 } | 408 } |
409 | 409 |
410 void RunClosureAfterAllPendingUIEvents(const base::Closure& closure) { | 410 void RunClosureAfterAllPendingUIEvents(const base::Closure& closure) { |
411 base::MessageLoop::current()->PostTask( | 411 base::ThreadTaskRunnerHandle::Get()->PostTask( |
412 FROM_HERE, base::Bind(&EventQueueWatcher, closure)); | 412 FROM_HERE, base::Bind(&EventQueueWatcher, closure)); |
413 } | 413 } |
414 | 414 |
415 bool IsFullKeyboardAccessEnabled() { | 415 bool IsFullKeyboardAccessEnabled() { |
416 return [NSApp isFullKeyboardAccessEnabled]; | 416 return [NSApp isFullKeyboardAccessEnabled]; |
417 } | 417 } |
418 | 418 |
419 } // namespace ui_controls | 419 } // namespace ui_controls |
OLD | NEW |