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/widget/native_widget_mac.h" | 5 #import "ui/views/widget/native_widget_mac.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
| 9 #import "base/mac/scoped_nsobject.h" |
9 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
11 #import "testing/gtest_mac.h" | 12 #import "testing/gtest_mac.h" |
12 #import "ui/events/test/cocoa_test_event_utils.h" | 13 #import "ui/events/test/cocoa_test_event_utils.h" |
13 #include "ui/events/test/event_generator.h" | 14 #include "ui/events/test/event_generator.h" |
14 #import "ui/gfx/mac/coordinate_conversion.h" | 15 #import "ui/gfx/mac/coordinate_conversion.h" |
| 16 #import "ui/views/cocoa/bridged_native_widget.h" |
15 #include "ui/views/controls/label.h" | 17 #include "ui/views/controls/label.h" |
16 #include "ui/views/native_cursor.h" | 18 #include "ui/views/native_cursor.h" |
17 #include "ui/views/test/test_widget_observer.h" | 19 #include "ui/views/test/test_widget_observer.h" |
18 #include "ui/views/test/widget_test.h" | 20 #include "ui/views/test/widget_test.h" |
| 21 #include "ui/views/widget/native_widget_private.h" |
19 | 22 |
20 namespace views { | 23 namespace views { |
21 namespace test { | 24 namespace test { |
22 | 25 |
23 // Tests for parts of NativeWidgetMac not covered by BridgedNativeWidget, which | 26 // Tests for parts of NativeWidgetMac not covered by BridgedNativeWidget, which |
24 // need access to Cocoa APIs. | 27 // need access to Cocoa APIs. |
25 typedef WidgetTest NativeWidgetMacTest; | 28 typedef WidgetTest NativeWidgetMacTest; |
26 | 29 |
27 class WidgetChangeObserver : public TestWidgetObserver { | 30 class WidgetChangeObserver : public TestWidgetObserver { |
28 public: | 31 public: |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 | 360 |
358 // Accessibility hit tests come in Cocoa screen coordinates. | 361 // Accessibility hit tests come in Cocoa screen coordinates. |
359 NSRect nsrect = gfx::ScreenRectToNSRect(screen_rect); | 362 NSRect nsrect = gfx::ScreenRectToNSRect(screen_rect); |
360 NSPoint midpoint = NSMakePoint(NSMidX(nsrect), NSMidY(nsrect)); | 363 NSPoint midpoint = NSMakePoint(NSMidX(nsrect), NSMidY(nsrect)); |
361 | 364 |
362 id hit = [widget->GetNativeWindow() accessibilityHitTest:midpoint]; | 365 id hit = [widget->GetNativeWindow() accessibilityHitTest:midpoint]; |
363 id title = [hit accessibilityAttributeValue:NSAccessibilityTitleAttribute]; | 366 id title = [hit accessibilityAttributeValue:NSAccessibilityTitleAttribute]; |
364 EXPECT_NSEQ(title, @"Green"); | 367 EXPECT_NSEQ(title, @"Green"); |
365 } | 368 } |
366 | 369 |
| 370 // Tests creating a views::Widget parented off a native NSWindow. |
| 371 TEST_F(NativeWidgetMacTest, NonWidgetParent) { |
| 372 NSRect parent_nsrect = NSMakeRect(100, 100, 300, 200); |
| 373 base::scoped_nsobject<NSWindow> native_parent( |
| 374 [[NSWindow alloc] initWithContentRect:parent_nsrect |
| 375 styleMask:NSBorderlessWindowMask |
| 376 backing:NSBackingStoreBuffered |
| 377 defer:NO]); |
| 378 [native_parent setReleasedWhenClosed:NO]; // Owned by scoped_nsobject. |
| 379 [native_parent makeKeyAndOrderFront:nil]; |
| 380 |
| 381 // Note: Don't use WidgetTest::CreateChildPlatformWidget because that makes |
| 382 // windows of TYPE_CONTROL which are automatically made visible. But still |
| 383 // mark it as a child to test window positioning. |
| 384 Widget* child = new Widget; |
| 385 Widget::InitParams init_params; |
| 386 init_params.parent = [native_parent contentView]; |
| 387 init_params.child = true; |
| 388 child->Init(init_params); |
| 389 |
| 390 TestWidgetObserver child_observer(child); |
| 391 |
| 392 // GetTopLevelNativeWidget() only goes as far as there exists a Widget (i.e. |
| 393 // must stop at |child|. |
| 394 internal::NativeWidgetPrivate* top_level_widget = |
| 395 internal::NativeWidgetPrivate::GetTopLevelNativeWidget( |
| 396 child->GetNativeView()); |
| 397 EXPECT_EQ(child, top_level_widget->GetWidget()); |
| 398 |
| 399 // To verify the parent, we need to use NativeWidgetMac APIs. |
| 400 BridgedNativeWidget* bridged_native_widget = |
| 401 NativeWidgetMac::GetBridgeForNativeWindow(child->GetNativeWindow()); |
| 402 EXPECT_EQ(native_parent, bridged_native_widget->parent()->GetNSWindow()); |
| 403 |
| 404 child->SetBounds(gfx::Rect(50, 50, 200, 100)); |
| 405 EXPECT_FALSE(child->IsVisible()); |
| 406 EXPECT_EQ(0u, [[native_parent childWindows] count]); |
| 407 |
| 408 child->Show(); |
| 409 EXPECT_TRUE(child->IsVisible()); |
| 410 EXPECT_EQ(1u, [[native_parent childWindows] count]); |
| 411 EXPECT_EQ(child->GetNativeWindow(), |
| 412 [[native_parent childWindows] objectAtIndex:0]); |
| 413 EXPECT_EQ(native_parent, [child->GetNativeWindow() parentWindow]); |
| 414 |
| 415 // Child should be positioned on screen relative to the parent, but note we |
| 416 // positioned the parent in Cooca coordinates, so we need to convert. |
| 417 gfx::Point parent_origin = gfx::ScreenRectFromNSRect(parent_nsrect).origin(); |
| 418 EXPECT_EQ(gfx::Rect(150, parent_origin.y() + 50, 200, 100), |
| 419 child->GetWindowBoundsInScreen()); |
| 420 |
| 421 // Closing the parent should close and destroy the child. |
| 422 EXPECT_FALSE(child_observer.widget_closed()); |
| 423 [native_parent close]; |
| 424 EXPECT_TRUE(child_observer.widget_closed()); |
| 425 |
| 426 EXPECT_EQ(0u, [[native_parent childWindows] count]); |
| 427 } |
| 428 |
367 } // namespace test | 429 } // namespace test |
368 } // namespace views | 430 } // namespace views |
OLD | NEW |