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

Side by Side Diff: ui/ui_controls/ui_controls_mac.mm

Issue 11419013: Add desktop vs. ash context to ui_controls Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup Created 8 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
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/ui_controls/ui_controls.h" 5 #include "ui/ui_controls/ui_controls.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #include <mach/mach_time.h> 8 #include <mach/mach_time.h>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 } 206 }
207 207
208 // Stores the current mouse location on the screen. So that we can use it 208 // Stores the current mouse location on the screen. So that we can use it
209 // when firing keyboard and mouse click events. 209 // when firing keyboard and mouse click events.
210 NSPoint g_mouse_location = { 0, 0 }; 210 NSPoint g_mouse_location = { 0, 0 };
211 211
212 } // namespace 212 } // namespace
213 213
214 namespace ui_controls { 214 namespace ui_controls {
215 215
216 bool SendKeyPress(gfx::NativeWindow window, 216 namespace {
217 ui::KeyboardCode key,
218 bool control,
219 bool shift,
220 bool alt,
221 bool command) {
222 return SendKeyPressNotifyWhenDone(window, key,
223 control, shift, alt, command,
224 base::Closure());
225 }
226 217
227 // Win and Linux implement a SendKeyPress() this as a 218 class UIControlsMac : public UIControls {
228 // SendKeyPressAndRelease(), so we should as well (despite the name). 219 public:
229 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window, 220 UIControlsMac() {}
230 ui::KeyboardCode key, 221 virtual ~UIControlsMac() {}
231 bool control,
232 bool shift,
233 bool alt,
234 bool command,
235 const base::Closure& task) {
236 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
237 222
238 std::vector<NSEvent*> events; 223 bool SendKeyPress(gfx::NativeWindow window,
239 SynthesizeKeyEventsSequence( 224 ui::KeyboardCode key,
240 window, key, control, shift, alt, command, &events); 225 bool control,
241 226 bool shift,
242 // TODO(suzhe): Using [NSApplication postEvent:atStart:] here causes 227 bool alt,
243 // BrowserKeyEventsTest.CommandKeyEvents to fail. See http://crbug.com/49270 228 bool command) OVERRIDE {
244 // But using [NSApplication sendEvent:] should be safe for keyboard events, 229 return SendKeyPressNotifyWhenDone(window, key,
245 // because until now, no code wants to retrieve the next event when handling 230 control, shift, alt, command,
246 // a keyboard event. 231 base::Closure());
247 for (std::vector<NSEvent*>::iterator iter = events.begin();
248 iter != events.end(); ++iter)
249 [[NSApplication sharedApplication] sendEvent:*iter];
250
251 if (!task.is_null()) {
252 MessageLoop::current()->PostTask(
253 FROM_HERE, base::Bind(&EventQueueWatcher, task));
254 } 232 }
255 233
256 return true; 234 // Win and Linux implement a SendKeyPress() this as a
257 } 235 // SendKeyPressAndRelease(), so we should as well (despite the name).
236 bool SendKeyPressNotifyWhenDone(gfx::NativeWindow window,
237 ui::KeyboardCode key,
238 bool control,
239 bool shift,
240 bool alt,
241 bool command,
242 const base::Closure& task) OVERRIDE {
243 DCHECK_EQ(MessageLoop::TYPE_UI, MessageLoop::current()->type());
258 244
259 bool SendMouseMove(long x, long y) { 245 std::vector<NSEvent*> events;
260 return SendMouseMoveNotifyWhenDone(x, y, base::Closure()); 246 SynthesizeKeyEventsSequence(
261 } 247 window, key, control, shift, alt, command, &events);
262 248
263 // Input position is in screen coordinates. However, NSMouseMoved 249 // TODO(suzhe): Using [NSApplication postEvent:atStart:] here causes
264 // events require them window-relative, so we adjust. We *DO* flip 250 // BrowserKeyEventsTest.CommandKeyEvents to fail. See http://crbug.com/49270
265 // the coordinate space, so input events can be the same for all 251 // But using [NSApplication sendEvent:] should be safe for keyboard events,
266 // platforms. E.g. (0,0) is upper-left. 252 // because until now, no code wants to retrieve the next event when handling
267 bool SendMouseMoveNotifyWhenDone(long x, long y, const base::Closure& task) { 253 // a keyboard event.
268 NSWindow* window = [[NSApplication sharedApplication] keyWindow]; 254 for (std::vector<NSEvent*>::iterator iter = events.begin();
269 CGFloat screenHeight = 255 iter != events.end(); ++iter)
270 [[[NSScreen screens] objectAtIndex:0] frame].size.height; 256 [[NSApplication sharedApplication] sendEvent:*iter];
271 g_mouse_location = NSMakePoint(x, screenHeight - y); // flip!
272 NSPoint pointInWindow = g_mouse_location;
273 if (window)
274 pointInWindow = [window convertScreenToBase:pointInWindow];
275 NSTimeInterval timestamp = TimeIntervalSinceSystemStartup();
276 257
277 NSEvent* event = 258 if (!task.is_null()) {
278 [NSEvent mouseEventWithType:NSMouseMoved 259 MessageLoop::current()->PostTask(
279 location:pointInWindow 260 FROM_HERE, base::Bind(&EventQueueWatcher, task));
280 modifierFlags:0 261 }
281 timestamp:timestamp
282 windowNumber:[window windowNumber]
283 context:nil
284 eventNumber:0
285 clickCount:0
286 pressure:0.0];
287 [[NSApplication sharedApplication] postEvent:event atStart:NO];
288 262
289 if (!task.is_null()) { 263 return true;
290 MessageLoop::current()->PostTask(
291 FROM_HERE, base::Bind(&EventQueueWatcher, task));
292 } 264 }
293 265
294 return true; 266 bool SendMouseMove(long x, long y) OVERRIDE {
295 } 267 return SendMouseMoveNotifyWhenDone(x, y, base::Closure());
296
297 bool SendMouseEvents(MouseButton type, int state) {
298 return SendMouseEventsNotifyWhenDone(type, state, base::Closure());
299 }
300
301 bool SendMouseEventsNotifyWhenDone(MouseButton type, int state,
302 const base::Closure& task) {
303 // On windows it appears state can be (UP|DOWN). It is unclear if
304 // that'll happen here but prepare for it just in case.
305 if (state == (UP|DOWN)) {
306 return (SendMouseEventsNotifyWhenDone(type, DOWN, base::Closure()) &&
307 SendMouseEventsNotifyWhenDone(type, UP, task));
308 }
309 NSEventType etype = 0;
310 if (type == LEFT) {
311 if (state == UP) {
312 etype = NSLeftMouseUp;
313 } else {
314 etype = NSLeftMouseDown;
315 }
316 } else if (type == MIDDLE) {
317 if (state == UP) {
318 etype = NSOtherMouseUp;
319 } else {
320 etype = NSOtherMouseDown;
321 }
322 } else if (type == RIGHT) {
323 if (state == UP) {
324 etype = NSRightMouseUp;
325 } else {
326 etype = NSRightMouseDown;
327 }
328 } else {
329 return false;
330 }
331 NSWindow* window = [[NSApplication sharedApplication] keyWindow];
332 NSPoint pointInWindow = g_mouse_location;
333 if (window)
334 pointInWindow = [window convertScreenToBase:pointInWindow];
335
336 NSEvent* event =
337 [NSEvent mouseEventWithType:etype
338 location:pointInWindow
339 modifierFlags:0
340 timestamp:TimeIntervalSinceSystemStartup()
341 windowNumber:[window windowNumber]
342 context:nil
343 eventNumber:0
344 clickCount:1
345 pressure:(state == DOWN ? 1.0 : 0.0 )];
346 [[NSApplication sharedApplication] postEvent:event atStart:NO];
347
348 if (!task.is_null()) {
349 MessageLoop::current()->PostTask(
350 FROM_HERE, base::Bind(&EventQueueWatcher, task));
351 } 268 }
352 269
353 return true; 270 // Input position is in screen coordinates. However, NSMouseMoved
354 } 271 // events require them window-relative, so we adjust. We *DO* flip
272 // the coordinate space, so input events can be the same for all
273 // platforms. E.g. (0,0) is upper-left.
274 bool SendMouseMoveNotifyWhenDone(
275 long x, long y, const base::Closure& task) OVERRIDE {
276 NSWindow* window = [[NSApplication sharedApplication] keyWindow];
277 CGFloat screenHeight =
278 [[[NSScreen screens] objectAtIndex:0] frame].size.height;
279 g_mouse_location = NSMakePoint(x, screenHeight - y); // flip!
280 NSPoint pointInWindow = g_mouse_location;
281 if (window)
282 pointInWindow = [window convertScreenToBase:pointInWindow];
283 NSTimeInterval timestamp = TimeIntervalSinceSystemStartup();
355 284
356 bool SendMouseClick(MouseButton type) { 285 NSEvent* event =
357 return SendMouseEventsNotifyWhenDone(type, UP|DOWN, base::Closure()); 286 [NSEvent mouseEventWithType:NSMouseMoved
287 location:pointInWindow
288 modifierFlags:0
289 timestamp:timestamp
290 windowNumber:[window windowNumber]
291 context:nil
292 eventNumber:0
293 clickCount:0
294 pressure:0.0];
295 [[NSApplication sharedApplication] postEvent:event atStart:NO];
296
297 if (!task.is_null()) {
298 MessageLoop::current()->PostTask(
299 FROM_HERE, base::Bind(&EventQueueWatcher, task));
300 }
301
302 return true;
303 }
304
305 bool SendMouseEvents(MouseButton type, int state) OVERRIDE {
306 return SendMouseEventsNotifyWhenDone(type, state, base::Closure());
307 }
308
309 bool SendMouseEventsNotifyWhenDone(MouseButton type, int state,
310 const base::Closure& task) OVERRIDE {
311 // On windows it appears state can be (UP|DOWN). It is unclear if
312 // that'll happen here but prepare for it just in case.
313 if (state == (UP|DOWN)) {
314 return (SendMouseEventsNotifyWhenDone(type, DOWN, base::Closure()) &&
315 SendMouseEventsNotifyWhenDone(type, UP, task));
316 }
317 NSEventType etype = 0;
318 if (type == LEFT) {
319 if (state == UP) {
320 etype = NSLeftMouseUp;
321 } else {
322 etype = NSLeftMouseDown;
323 }
324 } else if (type == MIDDLE) {
325 if (state == UP) {
326 etype = NSOtherMouseUp;
327 } else {
328 etype = NSOtherMouseDown;
329 }
330 } else if (type == RIGHT) {
331 if (state == UP) {
332 etype = NSRightMouseUp;
333 } else {
334 etype = NSRightMouseDown;
335 }
336 } else {
337 return false;
338 }
339 NSWindow* window = [[NSApplication sharedApplication] keyWindow];
340 NSPoint pointInWindow = g_mouse_location;
341 if (window)
342 pointInWindow = [window convertScreenToBase:pointInWindow];
343
344 NSEvent* event =
345 [NSEvent mouseEventWithType:etype
346 location:pointInWindow
347 modifierFlags:0
348 timestamp:TimeIntervalSinceSystemStartup()
349 windowNumber:[window windowNumber]
350 context:nil
351 eventNumber:0
352 clickCount:1
353 pressure:(state == DOWN ? 1.0 : 0.0 )];
354 [[NSApplication sharedApplication] postEvent:event atStart:NO];
355
356 if (!task.is_null()) {
357 MessageLoop::current()->PostTask(
358 FROM_HERE, base::Bind(&EventQueueWatcher, task));
359 }
360
361 return true;
362 }
363
364 bool SendMouseClick(MouseButton type) OVERRIDE {
365 return SendMouseEventsNotifyWhenDone(type, UP|DOWN, base::Closure());
366 }
367
368 private:
369 DISALLOW_COPY_AND_ASSIGN(UIControlsMac);
370 };
371
372 } // namespace
373
374 UIControls* CreateNativeUIControls() {
375 return new UIControlsMac;
358 } 376 }
359 377
360 } // namespace ui_controls 378 } // namespace ui_controls
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698