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
3 // found in the LICENSE file.
5 #include "ui/views/controls/native/native_view_host_mac.h"
7 #import <Cocoa/Cocoa.h>
9 #import "base/mac/scoped_nsobject.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "ui/views/controls/native/native_view_host.h"
12 #include "ui/views/controls/native/native_view_host_test_base.h"
13 #include "ui/views/view.h"
14 #include "ui/views/widget/widget.h"
18 class NativeViewHostMacTest : public test::NativeViewHostTestBase {
20 NativeViewHostMacTest() {}
22 NativeViewHostMac* native_host() {
23 return static_cast<NativeViewHostMac*>(GetNativeWrapper());
29 native_view_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
31 // Verify the expectation that the NativeViewHostWrapper is only created
32 // after the NativeViewHost is added to a widget.
33 EXPECT_FALSE(native_host());
34 toplevel()->GetRootView()->AddChildView(host());
35 EXPECT_TRUE(native_host());
37 host()->Attach(native_view_);
41 base::scoped_nsobject<NSView> native_view_;
44 DISALLOW_COPY_AND_ASSIGN(NativeViewHostMacTest);
47 // Test destroying the top level widget before destroying the NativeViewHost.
48 // On Mac, also ensure that the native view is removed from its superview when
49 // the Widget containing its host is destroyed.
50 TEST_F(NativeViewHostMacTest, DestroyWidget) {
51 ResetHostDestroyedCount();
54 EXPECT_EQ(0, host_destroyed_count());
55 EXPECT_TRUE([native_view_ superview]);
57 EXPECT_FALSE([native_view_ superview]);
58 EXPECT_EQ(1, host_destroyed_count());
61 // Ensure the native view receives the correct bounds when it is attached. On
62 // Mac, the bounds of the native view is relative to the NSWindow it is in, not
63 // the screen, and the coordinates have to be flipped.
64 TEST_F(NativeViewHostMacTest, Attach) {
66 EXPECT_TRUE([native_view_ superview]);
67 EXPECT_TRUE([native_view_ window]);
71 [native_view_ setFrame:NSZeroRect];
72 toplevel()->SetBounds(gfx::Rect(64, 48, 100, 200));
73 host()->SetBounds(10, 10, 80, 60);
75 EXPECT_FALSE([native_view_ superview]);
76 EXPECT_FALSE([native_view_ window]);
77 EXPECT_TRUE(NSEqualRects(NSZeroRect, [native_view_ frame]));
79 host()->Attach(native_view_);
80 EXPECT_TRUE([native_view_ superview]);
81 EXPECT_TRUE([native_view_ window]);
83 // Expect the top-left to be 10 pixels below the titlebar.
84 int bottom = toplevel()->GetClientAreaBoundsInScreen().height() - 10 - 60;
85 EXPECT_TRUE(NSEqualRects(NSMakeRect(10, bottom, 80, 60),
86 [native_view_ frame]));
89 // Ensure the native view is hidden along with its host, and when detaching, or
90 // when attaching to a host that is already hidden.
91 TEST_F(NativeViewHostMacTest, NativeViewHidden) {
93 toplevel()->SetBounds(gfx::Rect(0, 0, 100, 100));
94 host()->SetBounds(10, 10, 80, 60);
96 EXPECT_FALSE([native_view_ isHidden]);
97 host()->SetVisible(false);
98 EXPECT_TRUE([native_view_ isHidden]);
99 host()->SetVisible(true);
100 EXPECT_FALSE([native_view_ isHidden]);
103 EXPECT_TRUE([native_view_ isHidden]); // Hidden when detached.
104 [native_view_ setHidden:NO];
106 host()->SetVisible(false);
107 EXPECT_FALSE([native_view_ isHidden]); // Stays visible.
108 host()->Attach(native_view_);
109 EXPECT_TRUE([native_view_ isHidden]); // Hidden when attached.
112 [native_view_ setHidden:YES];
113 host()->SetVisible(true);
114 EXPECT_TRUE([native_view_ isHidden]); // Stays hidden.
115 host()->Attach(native_view_);
116 EXPECT_FALSE([native_view_ isHidden]); // Made visible when attached.
118 EXPECT_TRUE([native_view_ superview]);
119 toplevel()->GetRootView()->RemoveChildView(host());
120 EXPECT_TRUE([native_view_ isHidden]); // Hidden when removed from Widget.
121 EXPECT_FALSE([native_view_ superview]);
123 toplevel()->GetRootView()->AddChildView(host());
124 EXPECT_FALSE([native_view_ isHidden]); // And visible when added.
125 EXPECT_TRUE([native_view_ superview]);