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

Side by Side Diff: ui/views/cocoa/bridged_native_widget_interactive_uitest.mm

Issue 2475173002: MacViews: Fix window dragging on Sierra. (Closed)
Patch Set: Address comments. Created 4 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #import "ui/views/cocoa/bridged_native_widget.h" 5 #import "ui/views/cocoa/bridged_native_widget.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #import "base/mac/mac_util.h" 9 #import "base/mac/mac_util.h"
10 #import "base/mac/sdk_forward_declarations.h" 10 #import "base/mac/sdk_forward_declarations.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 namespace { 191 namespace {
192 192
193 // This is used to wait for reposted events to be seen. We can't just use 193 // This is used to wait for reposted events to be seen. We can't just use
194 // RunPendingMessages() because CGEventPost might not be synchronous. 194 // RunPendingMessages() because CGEventPost might not be synchronous.
195 class HitTestBridgedNativeWidget : public BridgedNativeWidget { 195 class HitTestBridgedNativeWidget : public BridgedNativeWidget {
196 public: 196 public:
197 explicit HitTestBridgedNativeWidget(NativeWidgetMac* widget) 197 explicit HitTestBridgedNativeWidget(NativeWidgetMac* widget)
198 : BridgedNativeWidget(widget) {} 198 : BridgedNativeWidget(widget) {}
199 199
200 // BridgedNativeWidget: 200 // BridgedNativeWidget:
201 bool ShouldRepostPendingLeftMouseDown(NSPoint location_in_window) override { 201 bool ShouldRepostPendingLeftMouseDown(NSEvent* event) override {
202 did_repost_ = BridgedNativeWidget::ShouldRepostPendingLeftMouseDown( 202 did_repost_ = BridgedNativeWidget::ShouldRepostPendingLeftMouseDown(event);
203 location_in_window);
204 203
205 if (run_loop_) 204 if (run_loop_)
206 run_loop_->Quit(); 205 run_loop_->Quit();
207 206
208 return did_repost_; 207 return did_repost_;
209 } 208 }
210 209
211 void WaitForShouldRepost() { 210 void WaitForShouldRepost() {
212 base::RunLoop run_loop; 211 base::RunLoop run_loop;
213 run_loop_ = &run_loop; 212 run_loop_ = &run_loop;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 test::HitTestNativeWidgetMac* native_widget = 315 test::HitTestNativeWidgetMac* native_widget =
317 new test::HitTestNativeWidgetMac(&widget, frame_view); 316 new test::HitTestNativeWidgetMac(&widget, frame_view);
318 HitTestWidgetDelegate* widget_delegate = new HitTestWidgetDelegate(&widget); 317 HitTestWidgetDelegate* widget_delegate = new HitTestWidgetDelegate(&widget);
319 Widget::InitParams init_params = 318 Widget::InitParams init_params =
320 CreateParams(Widget::InitParams::TYPE_WINDOW); 319 CreateParams(Widget::InitParams::TYPE_WINDOW);
321 init_params.native_widget = native_widget; 320 init_params.native_widget = native_widget;
322 init_params.delegate = widget_delegate; 321 init_params.delegate = widget_delegate;
323 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; 322 init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
324 init_params.bounds = gfx::Rect(100, 200, 400, 300); 323 init_params.bounds = gfx::Rect(100, 200, 400, 300);
325 widget.Init(init_params); 324 widget.Init(init_params);
325
326 WidgetActivationWaiter activation_waiter(&widget, true);
326 widget.Show(); 327 widget.Show();
328 activation_waiter.Wait();
327 329
328 // Points inside the resize area. 330 // Points inside the resize area.
329 const NSPoint bottom_right_point = {398, 2}; 331 const NSPoint bottom_right_point = {398, 2};
330 const NSPoint right_of_bottom_right = {398 + 10, 2}; 332 const NSPoint right_of_bottom_right = {398 + 10, 2};
331 333
332 NSWindow* window = widget.GetNativeWindow(); 334 NSWindow* window = widget.GetNativeWindow();
335
336 // This is required since BridgedNativeWidget::SetVisibilityState initially
337 // suppresses visibility and ignores mouse events for opaque non modal
338 // dialogs. For the test, undo these changes.
339 [window setIgnoresMouseEvents:NO];
340 [window setAlphaValue:1.0];
341
333 HitTestBridgedNativeWidget* bridge = native_widget->bridge(); 342 HitTestBridgedNativeWidget* bridge = native_widget->bridge();
334 343
344 const bool using_drag_event_monitor =
345 BridgedNativeWidget::ShouldUseDragEventMonitor();
346
335 // Dragging the window should work. 347 // Dragging the window should work.
336 frame_view->set_hit_test_result(HTCAPTION); 348 frame_view->set_hit_test_result(HTCAPTION);
337 { 349 {
338 EXPECT_EQ(100, [window frame].origin.x); 350 EXPECT_EQ(100, [window frame].origin.x);
339 351
352 base::scoped_nsobject<WindowedNSNotificationObserver> will_move_observer(
353 [[WindowedNSNotificationObserver alloc]
354 initForNotification:NSWindowWillMoveNotification]);
340 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( 355 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow(
341 NSMakePoint(20, 20), window); 356 NSMakePoint(20, 20), window);
342 EXPECT_FALSE(bridge->IsDraggable()); 357 EXPECT_FALSE(bridge->IsDraggable());
343 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); 358 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]);
344 bridge->WaitForShouldRepost(); 359 if (using_drag_event_monitor) {
345 EXPECT_TRUE(bridge->did_repost()); 360 bridge->WaitForShouldRepost();
346 EXPECT_TRUE(bridge->IsDraggable()); 361 EXPECT_TRUE(bridge->did_repost());
347 bridge->WaitForShouldRepost(); 362 EXPECT_TRUE(bridge->IsDraggable());
348 EXPECT_FALSE(bridge->did_repost()); 363 bridge->WaitForShouldRepost();
349 EXPECT_FALSE(bridge->IsDraggable()); 364 EXPECT_FALSE(bridge->did_repost());
365 EXPECT_FALSE(bridge->IsDraggable());
366 } else {
367 WaitForEvent(NSLeftMouseDownMask);
368 }
350 369
351 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( 370 base::scoped_nsobject<WindowedNSNotificationObserver> did_move_observer(
352 [[WindowedNSNotificationObserver alloc] 371 [[WindowedNSNotificationObserver alloc]
353 initForNotification:NSWindowDidMoveNotification]); 372 initForNotification:NSWindowDidMoveNotification]);
354 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( 373 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow(
355 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0); 374 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0);
356 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); 375 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]);
357 [ns_observer wait]; 376 WaitForEvent(NSLeftMouseDraggedMask);
377 // NSWindowWillMoveNotification should have been observed by the time the
378 // mouse drag event is received.
379 EXPECT_EQ(1, [will_move_observer notificationCount]);
380 EXPECT_TRUE([did_move_observer wait]);
358 EXPECT_EQ(110, [window frame].origin.x); 381 EXPECT_EQ(110, [window frame].origin.x);
359 382
360 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( 383 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow(
361 NSMakePoint(20, 20), NSLeftMouseUp, window, 0); 384 NSMakePoint(20, 20), NSLeftMouseUp, window, 0);
362 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); 385 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]);
363 WaitForEvent(NSLeftMouseUpMask); 386 WaitForEvent(NSLeftMouseUpMask);
364 EXPECT_EQ(110, [window frame].origin.x); 387 EXPECT_EQ(110, [window frame].origin.x);
365 } 388 }
366 389
367 // Dragging in the resize area works since the widget is not resizable. 390 // Dragging in the resize area works since the widget is not resizable.
368 { 391 {
369 EXPECT_EQ(110, [window frame].origin.x); 392 EXPECT_EQ(110, [window frame].origin.x);
370 393
394 base::scoped_nsobject<WindowedNSNotificationObserver> will_move_observer(
395 [[WindowedNSNotificationObserver alloc]
396 initForNotification:NSWindowWillMoveNotification]);
371 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( 397 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow(
372 bottom_right_point, window); 398 bottom_right_point, window);
373 EXPECT_FALSE(bridge->IsDraggable()); 399 EXPECT_FALSE(bridge->IsDraggable());
374 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); 400 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]);
375 bridge->WaitForShouldRepost(); 401 if (using_drag_event_monitor) {
376 EXPECT_TRUE(bridge->did_repost()); 402 bridge->WaitForShouldRepost();
377 EXPECT_TRUE(bridge->IsDraggable()); 403 EXPECT_TRUE(bridge->did_repost());
378 bridge->WaitForShouldRepost(); 404 EXPECT_TRUE(bridge->IsDraggable());
379 EXPECT_FALSE(bridge->did_repost()); 405 bridge->WaitForShouldRepost();
380 EXPECT_FALSE(bridge->IsDraggable()); 406 EXPECT_FALSE(bridge->did_repost());
407 EXPECT_FALSE(bridge->IsDraggable());
408 } else {
409 WaitForEvent(NSLeftMouseDownMask);
410 }
381 411
382 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( 412 base::scoped_nsobject<WindowedNSNotificationObserver> did_move_observer(
383 [[WindowedNSNotificationObserver alloc] 413 [[WindowedNSNotificationObserver alloc]
384 initForNotification:NSWindowDidMoveNotification]); 414 initForNotification:NSWindowDidMoveNotification]);
385 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( 415 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow(
386 right_of_bottom_right, NSLeftMouseDragged, window, 0); 416 right_of_bottom_right, NSLeftMouseDragged, window, 0);
387 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); 417 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]);
388 [ns_observer wait]; 418 WaitForEvent(NSLeftMouseDraggedMask);
419 EXPECT_EQ(1, [will_move_observer notificationCount]);
420 EXPECT_TRUE([did_move_observer wait]);
389 EXPECT_EQ(120, [window frame].origin.x); 421 EXPECT_EQ(120, [window frame].origin.x);
390 422
391 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( 423 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow(
392 bottom_right_point, NSLeftMouseUp, window, 0); 424 bottom_right_point, NSLeftMouseUp, window, 0);
393 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); 425 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]);
394 WaitForEvent(NSLeftMouseUpMask); 426 WaitForEvent(NSLeftMouseUpMask);
395 EXPECT_EQ(120, [window frame].origin.x); 427 EXPECT_EQ(120, [window frame].origin.x);
396 } 428 }
397 429
398 // If the widget is resizable, dragging in the resize area should not repost 430 // If the widget is resizable, dragging in the resize area should not repost
399 // (and should resize). 431 // (and should resize).
400 widget_delegate->set_can_resize(true); 432 widget_delegate->set_can_resize(true);
401 { 433 {
402 EXPECT_EQ(400, [window frame].size.width); 434 EXPECT_EQ(400, [window frame].size.width);
403 435
404 NSUInteger x = [window frame].origin.x; 436 NSUInteger x = [window frame].origin.x;
405 NSUInteger y = [window frame].origin.y; 437 NSUInteger y = [window frame].origin.y;
406 438
407 // Enqueue all mouse events first because AppKit will run its own loop to 439 // Enqueue all mouse events first because AppKit will run its own loop to
408 // consume them. 440 // consume them.
409 441 base::scoped_nsobject<WindowedNSNotificationObserver> will_move_observer(
442 [[WindowedNSNotificationObserver alloc]
443 initForNotification:NSWindowWillMoveNotification]);
410 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( 444 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow(
411 bottom_right_point, window); 445 bottom_right_point, window);
412 EXPECT_FALSE(bridge->IsDraggable()); 446 EXPECT_FALSE(bridge->IsDraggable());
413 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); 447 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]);
414 448
449 base::scoped_nsobject<WindowedNSNotificationObserver> did_resize_observer(
450 [[WindowedNSNotificationObserver alloc]
451 initForNotification:NSWindowDidResizeNotification]);
415 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPoint( 452 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPoint(
416 NSMakePoint(x + 408, y + 2), NSLeftMouseDragged, 0); 453 NSMakePoint(x + 408, y + 2), NSLeftMouseDragged, 0);
417 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); 454 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]);
418 455
419 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPoint( 456 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPoint(
420 NSMakePoint(x + 408, y + 2), NSLeftMouseUp, 0); 457 NSMakePoint(x + 408, y + 2), NSLeftMouseUp, 0);
421 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); 458 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]);
422 459
423 // The only event observed by us is the original mouse-down. It should not 460 if (using_drag_event_monitor) {
424 // be reposted. 461 // The only event observed by us is the original mouse-down. It should not
425 bridge->WaitForShouldRepost(); 462 // be reposted.
426 EXPECT_FALSE(bridge->did_repost()); 463 bridge->WaitForShouldRepost();
427 EXPECT_FALSE(bridge->IsDraggable()); 464 EXPECT_FALSE(bridge->did_repost());
465 EXPECT_FALSE(bridge->IsDraggable());
466 }
467
468 EXPECT_TRUE([did_resize_observer wait]);
469 EXPECT_EQ(0, [will_move_observer notificationCount]);
428 EXPECT_EQ(410, [window frame].size.width); 470 EXPECT_EQ(410, [window frame].size.width);
429 471
430 // Origin is unchanged. 472 // Origin is unchanged.
431 EXPECT_EQ(x, [window frame].origin.x); 473 EXPECT_EQ(x, [window frame].origin.x);
432 EXPECT_EQ(y, [window frame].origin.y); 474 EXPECT_EQ(y, [window frame].origin.y);
433 } 475 }
434 476
435 // Mouse-downs on the window controls should not be intercepted. 477 // Mouse-downs on the window controls should not be intercepted.
436 { 478 {
437 EXPECT_EQ(120, [window frame].origin.x); 479 EXPECT_EQ(120, [window frame].origin.x);
438 480
439 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( 481 base::scoped_nsobject<WindowedNSNotificationObserver> will_move_observer(
440 [[WindowedNSNotificationObserver alloc] 482 [[WindowedNSNotificationObserver alloc]
483 initForNotification:NSWindowWillMoveNotification]);
484 base::scoped_nsobject<WindowedNSNotificationObserver>
485 did_miniaturize_observer([[WindowedNSNotificationObserver alloc]
441 initForNotification:NSWindowDidMiniaturizeNotification]); 486 initForNotification:NSWindowDidMiniaturizeNotification]);
442 487
443 // Position this on the minimize button. 488 // Position this on the minimize button.
444 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( 489 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow(
445 NSMakePoint(30, 290), window); 490 NSMakePoint(30, 290), window);
446 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); 491 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]);
447 492
448 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( 493 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow(
449 NSMakePoint(30, 290), NSLeftMouseUp, window, 0); 494 NSMakePoint(30, 290), NSLeftMouseUp, window, 0);
450 EXPECT_FALSE([window isMiniaturized]); 495 EXPECT_FALSE([window isMiniaturized]);
451 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); 496 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]);
452 [ns_observer wait]; 497 [did_miniaturize_observer wait];
498 EXPECT_EQ(0, [will_move_observer notificationCount]);
453 EXPECT_TRUE([window isMiniaturized]); 499 EXPECT_TRUE([window isMiniaturized]);
454 [window deminiaturize:nil]; 500 [window deminiaturize:nil];
455 501
456 // Position unchanged. 502 // Position unchanged.
457 EXPECT_EQ(120, [window frame].origin.x); 503 EXPECT_EQ(120, [window frame].origin.x);
458 } 504 }
459 505
460 // Non-draggable areas should do nothing. 506 // Non-draggable areas should do nothing.
461 frame_view->set_hit_test_result(HTCLIENT); 507 frame_view->set_hit_test_result(HTCLIENT);
462 { 508 {
463 EXPECT_EQ(120, [window frame].origin.x); 509 EXPECT_EQ(120, [window frame].origin.x);
464 510
511 base::scoped_nsobject<WindowedNSNotificationObserver> will_move_observer(
512 [[WindowedNSNotificationObserver alloc]
513 initForNotification:NSWindowWillMoveNotification]);
465 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( 514 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow(
466 NSMakePoint(20, 20), window); 515 NSMakePoint(20, 20), window);
467 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); 516 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]);
468 WaitForEvent(NSLeftMouseDownMask); 517 WaitForEvent(NSLeftMouseDownMask);
469 518
470 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( 519 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow(
471 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0); 520 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0);
472 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); 521 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]);
473 WaitForEvent(NSLeftMouseDraggedMask); 522 WaitForEvent(NSLeftMouseDraggedMask);
523 EXPECT_EQ(0, [will_move_observer notificationCount]);
474 EXPECT_EQ(120, [window frame].origin.x); 524 EXPECT_EQ(120, [window frame].origin.x);
475 525
476 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( 526 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow(
477 NSMakePoint(30, 30), NSLeftMouseUp, window, 0); 527 NSMakePoint(30, 30), NSLeftMouseUp, window, 0);
478 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); 528 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]);
479 WaitForEvent(NSLeftMouseUpMask); 529 WaitForEvent(NSLeftMouseUpMask);
480 EXPECT_EQ(120, [window frame].origin.x); 530 EXPECT_EQ(120, [window frame].origin.x);
481 } 531 }
482 } 532 }
483 533
484 } // namespace test 534 } // namespace test
485 } // namespace views 535 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698