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

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

Powered by Google App Engine
This is Rietveld 408576698