Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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]; | |
|
karandeepb
2016/11/08 02:59:03
What would be a good workaround to avoid this, sin
tapted
2016/11/08 05:03:17
I think if WindowResizeHelperMac::Get()->task_runn
karandeepb
2016/11/09 04:44:20
Weirdly, even after commenting this out, I can't s
tapted
2016/11/09 05:06:56
yah - OSX uses the alpha channel of the window for
karandeepb
2016/11/09 06:33:22
Yeah, you are correct. CALayer's alpha is also inf
tapted
2016/11/10 00:43:20
No task runner means no GPU process, which could h
karandeepb
2016/11/10 02:44:43
Acknowledged. Also, updated the comment regarding
| |
| 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 |
| 340 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( | 352 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( |
| 341 NSMakePoint(20, 20), window); | 353 NSMakePoint(20, 20), window); |
| 342 EXPECT_FALSE(bridge->IsDraggable()); | 354 EXPECT_FALSE(bridge->IsDraggable()); |
| 343 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); | 355 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); |
| 344 bridge->WaitForShouldRepost(); | 356 if (using_drag_event_monitor) { |
| 345 EXPECT_TRUE(bridge->did_repost()); | 357 bridge->WaitForShouldRepost(); |
| 346 EXPECT_TRUE(bridge->IsDraggable()); | 358 EXPECT_TRUE(bridge->did_repost()); |
| 347 bridge->WaitForShouldRepost(); | 359 EXPECT_TRUE(bridge->IsDraggable()); |
| 348 EXPECT_FALSE(bridge->did_repost()); | 360 bridge->WaitForShouldRepost(); |
| 349 EXPECT_FALSE(bridge->IsDraggable()); | 361 EXPECT_FALSE(bridge->did_repost()); |
| 362 EXPECT_FALSE(bridge->IsDraggable()); | |
| 363 } else { | |
| 364 WaitForEvent(NSLeftMouseDownMask); | |
| 365 } | |
| 350 | 366 |
| 351 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( | 367 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( |
|
tapted
2016/11/08 05:03:17
maybe we want to rename this to, e.g., move_observ
karandeepb
2016/11/09 04:44:20
Done.
| |
| 352 [[WindowedNSNotificationObserver alloc] | 368 [[WindowedNSNotificationObserver alloc] |
| 353 initForNotification:NSWindowDidMoveNotification]); | 369 initForNotification:NSWindowDidMoveNotification]); |
| 354 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( | 370 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( |
| 355 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0); | 371 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0); |
| 356 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); | 372 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); |
| 357 [ns_observer wait]; | 373 EXPECT_TRUE([ns_observer wait]); |
| 358 EXPECT_EQ(110, [window frame].origin.x); | 374 EXPECT_EQ(110, [window frame].origin.x); |
| 359 | 375 |
| 360 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( | 376 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( |
| 361 NSMakePoint(20, 20), NSLeftMouseUp, window, 0); | 377 NSMakePoint(20, 20), NSLeftMouseUp, window, 0); |
| 362 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); | 378 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); |
| 363 WaitForEvent(NSLeftMouseUpMask); | 379 WaitForEvent(NSLeftMouseUpMask); |
| 364 EXPECT_EQ(110, [window frame].origin.x); | 380 EXPECT_EQ(110, [window frame].origin.x); |
| 365 } | 381 } |
| 366 | 382 |
| 367 // Dragging in the resize area works since the widget is not resizable. | 383 // Dragging in the resize area works since the widget is not resizable. |
| 368 { | 384 { |
| 369 EXPECT_EQ(110, [window frame].origin.x); | 385 EXPECT_EQ(110, [window frame].origin.x); |
| 370 | 386 |
| 371 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( | 387 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( |
| 372 bottom_right_point, window); | 388 bottom_right_point, window); |
| 373 EXPECT_FALSE(bridge->IsDraggable()); | 389 EXPECT_FALSE(bridge->IsDraggable()); |
| 374 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); | 390 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); |
| 375 bridge->WaitForShouldRepost(); | 391 if (using_drag_event_monitor) { |
| 376 EXPECT_TRUE(bridge->did_repost()); | 392 bridge->WaitForShouldRepost(); |
| 377 EXPECT_TRUE(bridge->IsDraggable()); | 393 EXPECT_TRUE(bridge->did_repost()); |
| 378 bridge->WaitForShouldRepost(); | 394 EXPECT_TRUE(bridge->IsDraggable()); |
| 379 EXPECT_FALSE(bridge->did_repost()); | 395 bridge->WaitForShouldRepost(); |
| 380 EXPECT_FALSE(bridge->IsDraggable()); | 396 EXPECT_FALSE(bridge->did_repost()); |
| 397 EXPECT_FALSE(bridge->IsDraggable()); | |
| 398 } else { | |
| 399 WaitForEvent(NSLeftMouseDownMask); | |
| 400 } | |
| 381 | 401 |
| 382 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( | 402 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( |
| 383 [[WindowedNSNotificationObserver alloc] | 403 [[WindowedNSNotificationObserver alloc] |
| 384 initForNotification:NSWindowDidMoveNotification]); | 404 initForNotification:NSWindowDidMoveNotification]); |
| 385 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( | 405 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( |
| 386 right_of_bottom_right, NSLeftMouseDragged, window, 0); | 406 right_of_bottom_right, NSLeftMouseDragged, window, 0); |
| 387 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); | 407 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); |
| 388 [ns_observer wait]; | 408 EXPECT_TRUE([ns_observer wait]); |
| 389 EXPECT_EQ(120, [window frame].origin.x); | 409 EXPECT_EQ(120, [window frame].origin.x); |
| 390 | 410 |
| 391 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( | 411 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( |
| 392 bottom_right_point, NSLeftMouseUp, window, 0); | 412 bottom_right_point, NSLeftMouseUp, window, 0); |
| 393 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); | 413 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); |
| 394 WaitForEvent(NSLeftMouseUpMask); | 414 WaitForEvent(NSLeftMouseUpMask); |
| 395 EXPECT_EQ(120, [window frame].origin.x); | 415 EXPECT_EQ(120, [window frame].origin.x); |
| 396 } | 416 } |
| 397 | 417 |
| 398 // If the widget is resizable, dragging in the resize area should not repost | 418 // If the widget is resizable, dragging in the resize area should not repost |
| 399 // (and should resize). | 419 // (and should resize). |
| 400 widget_delegate->set_can_resize(true); | 420 widget_delegate->set_can_resize(true); |
| 401 { | 421 { |
| 402 EXPECT_EQ(400, [window frame].size.width); | 422 EXPECT_EQ(400, [window frame].size.width); |
| 403 | 423 |
| 404 NSUInteger x = [window frame].origin.x; | 424 NSUInteger x = [window frame].origin.x; |
| 405 NSUInteger y = [window frame].origin.y; | 425 NSUInteger y = [window frame].origin.y; |
| 406 | 426 |
| 407 // Enqueue all mouse events first because AppKit will run its own loop to | 427 // Enqueue all mouse events first because AppKit will run its own loop to |
| 408 // consume them. | 428 // consume them. |
| 409 | 429 |
| 410 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( | 430 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( |
| 411 bottom_right_point, window); | 431 bottom_right_point, window); |
| 412 EXPECT_FALSE(bridge->IsDraggable()); | 432 EXPECT_FALSE(bridge->IsDraggable()); |
| 413 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); | 433 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); |
| 414 | 434 |
| 435 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( | |
| 436 [[WindowedNSNotificationObserver alloc] | |
| 437 initForNotification:NSWindowDidResizeNotification]); | |
| 415 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPoint( | 438 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPoint( |
| 416 NSMakePoint(x + 408, y + 2), NSLeftMouseDragged, 0); | 439 NSMakePoint(x + 408, y + 2), NSLeftMouseDragged, 0); |
| 417 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); | 440 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); |
| 418 | 441 |
| 419 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPoint( | 442 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPoint( |
| 420 NSMakePoint(x + 408, y + 2), NSLeftMouseUp, 0); | 443 NSMakePoint(x + 408, y + 2), NSLeftMouseUp, 0); |
| 421 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); | 444 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); |
| 422 | 445 |
| 423 // The only event observed by us is the original mouse-down. It should not | 446 if (using_drag_event_monitor) { |
| 424 // be reposted. | 447 // The only event observed by us is the original mouse-down. It should not |
| 425 bridge->WaitForShouldRepost(); | 448 // be reposted. |
| 426 EXPECT_FALSE(bridge->did_repost()); | 449 bridge->WaitForShouldRepost(); |
| 427 EXPECT_FALSE(bridge->IsDraggable()); | 450 EXPECT_FALSE(bridge->did_repost()); |
| 451 EXPECT_FALSE(bridge->IsDraggable()); | |
| 452 } | |
| 453 | |
| 454 EXPECT_TRUE([ns_observer wait]); | |
| 428 EXPECT_EQ(410, [window frame].size.width); | 455 EXPECT_EQ(410, [window frame].size.width); |
| 429 | 456 |
| 430 // Origin is unchanged. | 457 // Origin is unchanged. |
| 431 EXPECT_EQ(x, [window frame].origin.x); | 458 EXPECT_EQ(x, [window frame].origin.x); |
| 432 EXPECT_EQ(y, [window frame].origin.y); | 459 EXPECT_EQ(y, [window frame].origin.y); |
| 433 } | 460 } |
| 434 | 461 |
| 435 // Mouse-downs on the window controls should not be intercepted. | 462 // Mouse-downs on the window controls should not be intercepted. |
| 436 { | 463 { |
| 437 EXPECT_EQ(120, [window frame].origin.x); | 464 EXPECT_EQ(120, [window frame].origin.x); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 460 // Non-draggable areas should do nothing. | 487 // Non-draggable areas should do nothing. |
| 461 frame_view->set_hit_test_result(HTCLIENT); | 488 frame_view->set_hit_test_result(HTCLIENT); |
| 462 { | 489 { |
| 463 EXPECT_EQ(120, [window frame].origin.x); | 490 EXPECT_EQ(120, [window frame].origin.x); |
| 464 | 491 |
| 465 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( | 492 NSEvent* mouse_down = cocoa_test_event_utils::LeftMouseDownAtPointInWindow( |
| 466 NSMakePoint(20, 20), window); | 493 NSMakePoint(20, 20), window); |
| 467 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); | 494 CGEventPost(kCGSessionEventTap, [mouse_down CGEvent]); |
| 468 WaitForEvent(NSLeftMouseDownMask); | 495 WaitForEvent(NSLeftMouseDownMask); |
| 469 | 496 |
| 497 base::scoped_nsobject<WindowedNSNotificationObserver> ns_observer( | |
| 498 [[WindowedNSNotificationObserver alloc] | |
| 499 initForNotification:NSWindowDidMoveNotification]); | |
| 470 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( | 500 NSEvent* mouse_drag = cocoa_test_event_utils::MouseEventAtPointInWindow( |
| 471 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0); | 501 NSMakePoint(30, 30), NSLeftMouseDragged, window, 0); |
| 472 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); | 502 CGEventPost(kCGSessionEventTap, [mouse_drag CGEvent]); |
| 473 WaitForEvent(NSLeftMouseDraggedMask); | 503 EXPECT_FALSE([ns_observer wait]); |
|
karandeepb
2016/11/08 02:59:03
This causes a RunLoop to run till the timeout. Can
tapted
2016/11/08 05:03:17
Hrm. Doesn't that make this effectively ::sleep(te
karandeepb
2016/11/09 04:44:20
Yeah it does.
| |
| 474 EXPECT_EQ(120, [window frame].origin.x); | 504 EXPECT_EQ(120, [window frame].origin.x); |
| 475 | 505 |
| 476 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( | 506 NSEvent* mouse_up = cocoa_test_event_utils::MouseEventAtPointInWindow( |
| 477 NSMakePoint(30, 30), NSLeftMouseUp, window, 0); | 507 NSMakePoint(30, 30), NSLeftMouseUp, window, 0); |
| 478 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); | 508 CGEventPost(kCGSessionEventTap, [mouse_up CGEvent]); |
| 479 WaitForEvent(NSLeftMouseUpMask); | 509 WaitForEvent(NSLeftMouseUpMask); |
| 480 EXPECT_EQ(120, [window frame].origin.x); | 510 EXPECT_EQ(120, [window frame].origin.x); |
| 481 } | 511 } |
| 482 } | 512 } |
| 483 | 513 |
| 484 } // namespace test | 514 } // namespace test |
| 485 } // namespace views | 515 } // namespace views |
| OLD | NEW |