Commit 5ee3db98 authored by tapted's avatar tapted Committed by Commit bot

MacViews: Implement NativeViewHostMac (take 3)

This is done in a comparable way to NativeViewHostAura, but using a
ReparentNSView helper function which reparents an NSView to a
NativeWidgetMac's BridgedContentView (or to `nil`).

Earlier attempts tried to use NativeWidgetPrivate::ReparentNativeView()
which turns out to be a bad idea, since it's really designed to reparent
windows (aura::Windows or HWNDs). Mac's child window support is
insufficient for what toolkit-views expects, and WebContents on Mac are
managed by an NSView in any case, not an NSWindow.

Along with logic currently in render_widget_host_view_mac.mm and
web_contents_view_mac.mm, reparenting renderer views needs to be done in
the native view hierarchy, not the window hierarchy.

This CL no longer tries to enable the current
native_view_host_unittest.cc (tests there assume ReparentNativeView is
used), but adds native_view_host_mac_unittest.mm to give test coverage,
and to inspect properties at the Cocoa layer. Common parts of the 3
_unittest.* files are refactored into a NativeViewHostTestBase class.

Some other views_unittests are also made passing by implementing a
NativeViewHost::CreateWrapper that doesn't just return NULL:
4xFocusTraverslTest and NativeWidgetTest.GetTopLevelNativeWidget2

Before: 455 tests run 22 tests failed 21 tests crashed. After: 458 tests
run 22 tests failed 16 tests crashed.

BUG=378134, 415024

Review URL: https://codereview.chromium.org/530933002

Cr-Commit-Position: refs/heads/master@{#295618}
parent f78b37a6
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
#include "ui/views/view.h" #include "ui/views/view.h"
namespace views { namespace views {
namespace test {
class NativeViewHostTestBase;
}
class NativeViewHostAuraTest;
class NativeViewHostWrapper; class NativeViewHostWrapper;
// If a NativeViewHost's native view is a Widget, this native window // If a NativeViewHost's native view is a Widget, this native window
...@@ -93,7 +95,7 @@ class VIEWS_EXPORT NativeViewHost : public View { ...@@ -93,7 +95,7 @@ class VIEWS_EXPORT NativeViewHost : public View {
virtual const char* GetClassName() const OVERRIDE; virtual const char* GetClassName() const OVERRIDE;
private: private:
friend class NativeViewHostAuraTest; friend class test::NativeViewHostTestBase;
// Detach the native view. |destroyed| is true if the native view is // Detach the native view. |destroyed| is true if the native view is
// detached because it's being destroyed, or false otherwise. // detached because it's being destroyed, or false otherwise.
......
...@@ -10,30 +10,13 @@ ...@@ -10,30 +10,13 @@
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursor.h"
#include "ui/views/controls/native/native_view_host.h" #include "ui/views/controls/native/native_view_host.h"
#include "ui/views/test/views_test_base.h" #include "ui/views/controls/native/native_view_host_test_base.h"
#include "ui/views/view.h" #include "ui/views/view.h"
#include "ui/views/view_constants_aura.h" #include "ui/views/view_constants_aura.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace views { namespace views {
// Testing wrapper of the NativeViewHost
class NativeViewHostTesting : public NativeViewHost {
public:
NativeViewHostTesting() {}
virtual ~NativeViewHostTesting() { destroyed_count_++; }
static void ResetDestroyedCount() { destroyed_count_ = 0; }
static int destroyed_count() { return destroyed_count_; }
private:
static int destroyed_count_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostTesting);
};
int NativeViewHostTesting::destroyed_count_ = 0;
// Observer watching for window visibility and bounds change events. This is // Observer watching for window visibility and bounds change events. This is
// used to verify that the child and clipping window operations are done in the // used to verify that the child and clipping window operations are done in the
// right order. // right order.
...@@ -91,21 +74,13 @@ class NativeViewHostWindowObserver : public aura::WindowObserver { ...@@ -91,21 +74,13 @@ class NativeViewHostWindowObserver : public aura::WindowObserver {
DISALLOW_COPY_AND_ASSIGN(NativeViewHostWindowObserver); DISALLOW_COPY_AND_ASSIGN(NativeViewHostWindowObserver);
}; };
class NativeViewHostAuraTest : public ViewsTestBase { class NativeViewHostAuraTest : public test::NativeViewHostTestBase {
public: public:
NativeViewHostAuraTest() { NativeViewHostAuraTest() {
} }
NativeViewHostAura* native_host() { NativeViewHostAura* native_host() {
return static_cast<NativeViewHostAura*>(host_->native_wrapper_.get()); return static_cast<NativeViewHostAura*>(GetNativeWrapper());
}
Widget* toplevel() {
return toplevel_.get();
}
NativeViewHost* host() {
return host_.get();
} }
Widget* child() { Widget* child() {
...@@ -115,38 +90,15 @@ class NativeViewHostAuraTest : public ViewsTestBase { ...@@ -115,38 +90,15 @@ class NativeViewHostAuraTest : public ViewsTestBase {
aura::Window* clipping_window() { return &(native_host()->clipping_window_); } aura::Window* clipping_window() { return &(native_host()->clipping_window_); }
void CreateHost() { void CreateHost() {
// Create the top level widget. CreateTopLevel();
toplevel_.reset(new Widget); CreateTestingHost();
Widget::InitParams toplevel_params = child_.reset(CreateChildForHost(toplevel()->GetNativeView(),
CreateParams(Widget::InitParams::TYPE_WINDOW); toplevel()->GetRootView(),
toplevel_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; new View,
toplevel_->Init(toplevel_params); host()));
// And the child widget.
child_.reset(new Widget);
Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
child_params.parent = toplevel_->GetNativeView();
child_->Init(child_params);
child_->SetContentsView(new View);
// Owned by |toplevel|.
host_.reset(new NativeViewHostTesting);
toplevel_->GetRootView()->AddChildView(host_.get());
host_->Attach(child_->GetNativeView());
} }
void DestroyHost() {
host_.reset();
}
NativeViewHostTesting* ReleaseHost() { return host_.release(); }
void DestroyTopLevel() { toplevel_.reset(); }
private: private:
scoped_ptr<Widget> toplevel_;
scoped_ptr<NativeViewHostTesting> host_;
scoped_ptr<Widget> child_; scoped_ptr<Widget> child_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostAuraTest); DISALLOW_COPY_AND_ASSIGN(NativeViewHostAuraTest);
...@@ -207,12 +159,12 @@ TEST_F(NativeViewHostAuraTest, CursorForNativeView) { ...@@ -207,12 +159,12 @@ TEST_F(NativeViewHostAuraTest, CursorForNativeView) {
// NativeViewHost works correctly. Specifically the associated NVH should be // NativeViewHost works correctly. Specifically the associated NVH should be
// destroyed and there shouldn't be any errors. // destroyed and there shouldn't be any errors.
TEST_F(NativeViewHostAuraTest, DestroyWidget) { TEST_F(NativeViewHostAuraTest, DestroyWidget) {
NativeViewHostTesting::ResetDestroyedCount(); ResetHostDestroyedCount();
CreateHost(); CreateHost();
ReleaseHost(); ReleaseHost();
EXPECT_EQ(0, NativeViewHostTesting::destroyed_count()); EXPECT_EQ(0, host_destroyed_count());
DestroyTopLevel(); DestroyTopLevel();
EXPECT_EQ(1, NativeViewHostTesting::destroyed_count()); EXPECT_EQ(1, host_destroyed_count());
} }
// Test that the fast resize path places the clipping and content windows were // Test that the fast resize path places the clipping and content windows were
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/controls/native/native_view_host_wrapper.h"
namespace views {
////////////////////////////////////////////////////////////////////////////////
// NativeViewHostWrapper, public:
// static
NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
NativeViewHost* host) {
return NULL;
}
} // namespace views
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_MAC_H_
#define UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_MAC_H_
#include "base/macros.h"
#include "ui/views/controls/native/native_view_host_wrapper.h"
#include "ui/views/views_export.h"
namespace views {
class NativeViewHost;
// Mac implementation of NativeViewHostWrapper.
class VIEWS_EXPORT NativeViewHostMac : public NativeViewHostWrapper {
public:
explicit NativeViewHostMac(NativeViewHost* host);
virtual ~NativeViewHostMac();
// Overridden from NativeViewHostWrapper:
virtual void AttachNativeView() OVERRIDE;
virtual void NativeViewDetaching(bool destroyed) OVERRIDE;
virtual void AddedToWidget() OVERRIDE;
virtual void RemovedFromWidget() OVERRIDE;
virtual void InstallClip(int x, int y, int w, int h) OVERRIDE;
virtual bool HasInstalledClip() OVERRIDE;
virtual void UninstallClip() OVERRIDE;
virtual void ShowWidget(int x, int y, int w, int h) OVERRIDE;
virtual void HideWidget() OVERRIDE;
virtual void SetFocus() OVERRIDE;
virtual gfx::NativeViewAccessible GetNativeViewAccessible() OVERRIDE;
virtual gfx::NativeCursor GetCursor(int x, int y) OVERRIDE;
private:
// Our associated NativeViewHost. Owns this.
NativeViewHost* host_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostMac);
};
} // namespace views
#endif // UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_AURA_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/controls/native/native_view_host_mac.h"
#import <Cocoa/Cocoa.h>
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#import "ui/views/cocoa/bridged_content_view.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/widget/widget.h"
namespace views {
namespace {
// Reparents |native_view| to be a child of the native content view of
// |new_parent|.
void ReparentNSView(NSView* native_view, Widget* new_parent) {
DCHECK(native_view);
// Mac's NativeViewHost has no support for hosting its own child widgets.
// This check is probably overly restrictive, since the Widget containing the
// NativeViewHost _is_ allowed child Widgets. However, we don't know yet
// whether those child Widgets need to be distinguished from Widgets that code
// might want to associate with the hosted NSView instead.
{
Widget::Widgets child_widgets;
Widget::GetAllChildWidgets(native_view, &child_widgets);
CHECK_GE(1u, child_widgets.size()); // 1 (itself) or 0 if detached.
}
if (!new_parent) {
[native_view removeFromSuperview];
return;
}
BridgedContentView* new_superview =
base::mac::ObjCCastStrict<BridgedContentView>(
new_parent->GetNativeView());
DCHECK(new_superview);
[new_superview addSubview:native_view];
}
} // namespace
NativeViewHostMac::NativeViewHostMac(NativeViewHost* host) : host_(host) {
}
NativeViewHostMac::~NativeViewHostMac() {
}
////////////////////////////////////////////////////////////////////////////////
// NativeViewHostMac, NativeViewHostWrapper implementation:
void NativeViewHostMac::AttachNativeView() {
DCHECK(host_->native_view());
ReparentNSView(host_->native_view(), host_->GetWidget());
}
void NativeViewHostMac::NativeViewDetaching(bool destroyed) {
// |destroyed| is only true if this class calls host_->NativeViewDestroyed().
// TODO(tapted): See if that's needed on Mac, since views are hard to destroy
// by themselves.
DCHECK(!destroyed);
[host_->native_view() setHidden:YES];
ReparentNSView(host_->native_view(), NULL);
}
void NativeViewHostMac::AddedToWidget() {
if (!host_->native_view())
return;
AttachNativeView();
host_->Layout();
}
void NativeViewHostMac::RemovedFromWidget() {
if (!host_->native_view())
return;
NativeViewDetaching(false);
}
void NativeViewHostMac::InstallClip(int x, int y, int w, int h) {
NOTIMPLEMENTED();
}
bool NativeViewHostMac::HasInstalledClip() {
return false;
}
void NativeViewHostMac::UninstallClip() {
NOTIMPLEMENTED();
}
void NativeViewHostMac::ShowWidget(int x, int y, int w, int h) {
if (host_->fast_resize())
NOTIMPLEMENTED();
// Coordinates will be from the top left of the parent Widget. The NativeView
// is already in the same NSWindow, so just flip to get Cooca coordinates and
// then convert to the containing view.
NSRect window_rect = NSMakeRect(
x,
host_->GetWidget()->GetClientAreaBoundsInScreen().height() - y - h,
w,
h);
// Convert window coordinates to the hosted view's superview, since that's how
// coordinates of the hosted view's frame is based.
NSRect container_rect =
[[host_->native_view() superview] convertRect:window_rect fromView:nil];
[host_->native_view() setFrame:container_rect];
[host_->native_view() setHidden:NO];
}
void NativeViewHostMac::HideWidget() {
[host_->native_view() setHidden:YES];
}
void NativeViewHostMac::SetFocus() {
if ([host_->native_view() acceptsFirstResponder])
[[host_->native_view() window] makeFirstResponder:host_->native_view()];
}
gfx::NativeViewAccessible NativeViewHostMac::GetNativeViewAccessible() {
return NULL;
}
gfx::NativeCursor NativeViewHostMac::GetCursor(int x, int y) {
NOTIMPLEMENTED();
return gfx::kNullCursor;
}
// static
NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
NativeViewHost* host) {
return new NativeViewHostMac(host);
}
} // namespace views
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/controls/native/native_view_host_mac.h"
#import <Cocoa/Cocoa.h>
#import "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/controls/native/native_view_host_test_base.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace views {
class NativeViewHostMacTest : public test::NativeViewHostTestBase {
public:
NativeViewHostMacTest() {}
NativeViewHostMac* native_host() {
return static_cast<NativeViewHostMac*>(GetNativeWrapper());
}
void CreateHost() {
CreateTopLevel();
CreateTestingHost();
native_view_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
// Verify the expectation that the NativeViewHostWrapper is only created
// after the NativeViewHost is added to a widget.
EXPECT_FALSE(native_host());
toplevel()->GetRootView()->AddChildView(host());
EXPECT_TRUE(native_host());
host()->Attach(native_view_);
}
protected:
base::scoped_nsobject<NSView> native_view_;
private:
DISALLOW_COPY_AND_ASSIGN(NativeViewHostMacTest);
};
// Test destroying the top level widget before destroying the NativeViewHost.
// On Mac, also ensure that the native view is removed from its superview when
// the Widget containing its host is destroyed.
TEST_F(NativeViewHostMacTest, DestroyWidget) {
ResetHostDestroyedCount();
CreateHost();
ReleaseHost();
EXPECT_EQ(0, host_destroyed_count());
EXPECT_TRUE([native_view_ superview]);
DestroyTopLevel();
EXPECT_FALSE([native_view_ superview]);
EXPECT_EQ(1, host_destroyed_count());
}
// Ensure the native view receives the correct bounds when it is attached. On
// Mac, the bounds of the native view is relative to the NSWindow it is in, not
// the screen, and the coordinates have to be flipped.
TEST_F(NativeViewHostMacTest, Attach) {
CreateHost();
EXPECT_TRUE([native_view_ superview]);
EXPECT_TRUE([native_view_ window]);
host()->Detach();
[native_view_ setFrame:NSZeroRect];
toplevel()->SetBounds(gfx::Rect(64, 48, 100, 200));
host()->SetBounds(10, 10, 80, 60);
EXPECT_FALSE([native_view_ superview]);
EXPECT_FALSE([native_view_ window]);
EXPECT_TRUE(NSEqualRects(NSZeroRect, [native_view_ frame]));
host()->Attach(native_view_);
EXPECT_TRUE([native_view_ superview]);
EXPECT_TRUE([native_view_ window]);
// Expect the top-left to be 10 pixels below the titlebar.
int bottom = toplevel()->GetClientAreaBoundsInScreen().height() - 10 - 60;
EXPECT_TRUE(NSEqualRects(NSMakeRect(10, bottom, 80, 60),
[native_view_ frame]));
}
// Ensure the native view is hidden along with its host, and when detaching, or
// when attaching to a host that is already hidden.
TEST_F(NativeViewHostMacTest, NativeViewHidden) {
CreateHost();
toplevel()->SetBounds(gfx::Rect(0, 0, 100, 100));
host()->SetBounds(10, 10, 80, 60);
EXPECT_FALSE([native_view_ isHidden]);
host()->SetVisible(false);
EXPECT_TRUE([native_view_ isHidden]);
host()->SetVisible(true);
EXPECT_FALSE([native_view_ isHidden]);
host()->Detach();
EXPECT_TRUE([native_view_ isHidden]); // Hidden when detached.
[native_view_ setHidden:NO];
host()->SetVisible(false);
EXPECT_FALSE([native_view_ isHidden]); // Stays visible.
host()->Attach(native_view_);
EXPECT_TRUE([native_view_ isHidden]); // Hidden when attached.
host()->Detach();
[native_view_ setHidden:YES];
host()->SetVisible(true);
EXPECT_TRUE([native_view_ isHidden]); // Stays hidden.
host()->Attach(native_view_);
EXPECT_FALSE([native_view_ isHidden]); // Made visible when attached.
EXPECT_TRUE([native_view_ superview]);
toplevel()->GetRootView()->RemoveChildView(host());
EXPECT_TRUE([native_view_ isHidden]); // Hidden when removed from Widget.
EXPECT_FALSE([native_view_ superview]);
toplevel()->GetRootView()->AddChildView(host());
EXPECT_FALSE([native_view_ isHidden]); // And visible when added.
EXPECT_TRUE([native_view_ superview]);
}
} // namespace views
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/controls/native/native_view_host_test_base.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/widget/widget.h"
namespace views {
namespace test {
// Testing wrapper of the NativeViewHost.
class NativeViewHostTestBase::NativeViewHostTesting : public NativeViewHost {
public:
explicit NativeViewHostTesting(NativeViewHostTestBase* owner)
: owner_(owner) {}
virtual ~NativeViewHostTesting() { owner_->host_destroyed_count_++; }
private:
NativeViewHostTestBase* owner_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostTesting);
};
NativeViewHostTestBase::NativeViewHostTestBase() : host_destroyed_count_(0) {
}
NativeViewHostTestBase::~NativeViewHostTestBase() {
}
void NativeViewHostTestBase::CreateTopLevel() {
toplevel_.reset(new Widget);
Widget::InitParams toplevel_params =
CreateParams(Widget::InitParams::TYPE_WINDOW);
toplevel_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
toplevel_->Init(toplevel_params);
}
void NativeViewHostTestBase::CreateTestingHost() {
host_.reset(new NativeViewHostTesting(this));
}
Widget* NativeViewHostTestBase::CreateChildForHost(
gfx::NativeView native_parent_view,
View* parent_view,
View* contents_view,
NativeViewHost* host) {
Widget* child = new Widget;
Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
child_params.parent = native_parent_view;
child->Init(child_params);
child->SetContentsView(contents_view);
// Owned by |parent_view|.
parent_view->AddChildView(host);
host->Attach(child->GetNativeView());
return child;
}
void NativeViewHostTestBase::DestroyTopLevel() {
toplevel_.reset();
}
void NativeViewHostTestBase::DestroyHost() {
host_.reset();
}
NativeViewHost* NativeViewHostTestBase::ReleaseHost() {
return host_.release();
}
NativeViewHostWrapper* NativeViewHostTestBase::GetNativeWrapper() {
return host_->native_wrapper_.get();
}
} // namespace test
} // namespace views
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "ui/views/test/views_test_base.h"
namespace views {
class NativeViewHost;
class NativeViewHostWrapper;
class Widget;
namespace test {
// Base class for NativeViewHost tests on different platforms.
class NativeViewHostTestBase : public ViewsTestBase {
public:
NativeViewHostTestBase();
virtual ~NativeViewHostTestBase();
// Create the |toplevel_| widget.
void CreateTopLevel();
// Create a testing |host_| that tracks destructor calls.
void CreateTestingHost();
// The number of times a host created by CreateHost() has been destroyed.
int host_destroyed_count() { return host_destroyed_count_; }
void ResetHostDestroyedCount() { host_destroyed_count_ = 0; }
// Create a child widget whose native parent is |native_parent_view|, uses
// |contents_view|, and is attached to |host| which is added as a child to
// |parent_view|. This effectively borrows the native content view from a
// newly created child Widget, and attaches it to |host|.
Widget* CreateChildForHost(gfx::NativeView native_parent_view,
View* parent_view,
View* contents_view,
NativeViewHost* host);
Widget* toplevel() { return toplevel_.get(); }
void DestroyTopLevel();
NativeViewHost* host() { return host_.get(); }
void DestroyHost();
NativeViewHost* ReleaseHost();
NativeViewHostWrapper* GetNativeWrapper();
private:
class NativeViewHostTesting;
scoped_ptr<Widget> toplevel_;
scoped_ptr<NativeViewHost> host_;
int host_destroyed_count_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostTestBase);
};
} // namespace test
} // namespace views
...@@ -7,55 +7,23 @@ ...@@ -7,55 +7,23 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/views/controls/native/native_view_host_test_base.h"
#include "ui/views/test/views_test_base.h" #include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
namespace views { namespace views {
class NativeViewHostTest : public ViewsTestBase { class NativeViewHostTest : public test::NativeViewHostTestBase {
public: public:
NativeViewHostTest() { NativeViewHostTest() {
} }
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
ViewsTestBase::SetUp(); ViewsTestBase::SetUp();
CreateTopLevel();
// Create the top level widget.
toplevel_.reset(new Widget);
Widget::InitParams toplevel_params =
CreateParams(Widget::InitParams::TYPE_WINDOW);
toplevel_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
toplevel_->Init(toplevel_params);
}
// Create a child widget whose native parent is |native_parent_view|, uses
// |contents_view|, and is attached to |host| which is added as a child to
// |parent_view|.
Widget* CreateChildForHost(gfx::NativeView native_parent_view,
View* parent_view,
View* contents_view,
NativeViewHost* host) {
Widget* child = new Widget;
Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
child_params.parent = native_parent_view;
child->Init(child_params);
child->SetContentsView(contents_view);
// Owned by |parent_view|.
parent_view->AddChildView(host);
host->Attach(child->GetNativeView());
return child;
}
Widget* toplevel() {
return toplevel_.get();
} }
private: private:
scoped_ptr<Widget> toplevel_;
DISALLOW_COPY_AND_ASSIGN(NativeViewHostTest); DISALLOW_COPY_AND_ASSIGN(NativeViewHostTest);
}; };
......
...@@ -135,7 +135,8 @@ ...@@ -135,7 +135,8 @@
'controls/native/native_view_host.h', 'controls/native/native_view_host.h',
'controls/native/native_view_host_aura.cc', 'controls/native/native_view_host_aura.cc',
'controls/native/native_view_host_aura.h', 'controls/native/native_view_host_aura.h',
'controls/native/native_view_host_mac.cc', 'controls/native/native_view_host_mac.h',
'controls/native/native_view_host_mac.mm',
'controls/prefix_delegate.h', 'controls/prefix_delegate.h',
'controls/prefix_selector.cc', 'controls/prefix_selector.cc',
'controls/prefix_selector.h', 'controls/prefix_selector.h',
...@@ -509,6 +510,9 @@ ...@@ -509,6 +510,9 @@
'controls/menu/menu_model_adapter_unittest.cc', 'controls/menu/menu_model_adapter_unittest.cc',
'controls/menu/menu_runner_cocoa_unittest.mm', 'controls/menu/menu_runner_cocoa_unittest.mm',
'controls/native/native_view_host_aura_unittest.cc', 'controls/native/native_view_host_aura_unittest.cc',
'controls/native/native_view_host_mac_unittest.mm',
'controls/native/native_view_host_test_base.h',
'controls/native/native_view_host_test_base.cc',
'controls/native/native_view_host_unittest.cc', 'controls/native/native_view_host_unittest.cc',
'controls/prefix_selector_unittest.cc', 'controls/prefix_selector_unittest.cc',
'controls/progress_bar_unittest.cc', 'controls/progress_bar_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment