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

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

Powered by Google App Engine
This is Rietveld 408576698