1 // Copyright (c) 2012 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_aura.h"
7 #include "base/logging.h"
8 #include "ui/aura/client/aura_constants.h"
9 #include "ui/aura/client/focus_client.h"
10 #include "ui/aura/window.h"
11 #include "ui/aura/window_delegate.h"
12 #include "ui/base/cursor/cursor.h"
13 #include "ui/base/hit_test.h"
14 #include "ui/views/controls/native/native_view_host.h"
15 #include "ui/views/view_constants_aura.h"
16 #include "ui/views/widget/widget.h"
20 class NativeViewHostAura::ClippingWindowDelegate
: public aura::WindowDelegate
{
22 ClippingWindowDelegate() : native_view_(NULL
) {}
23 ~ClippingWindowDelegate() override
{}
25 void set_native_view(aura::Window
* native_view
) {
26 native_view_
= native_view
;
29 gfx::Size
GetMinimumSize() const override
{ return gfx::Size(); }
30 gfx::Size
GetMaximumSize() const override
{ return gfx::Size(); }
31 void OnBoundsChanged(const gfx::Rect
& old_bounds
,
32 const gfx::Rect
& new_bounds
) override
{}
33 ui::TextInputClient
* GetFocusedTextInputClient() override
{ return nullptr; }
34 gfx::NativeCursor
GetCursor(const gfx::Point
& point
) override
{
35 return gfx::kNullCursor
;
37 int GetNonClientComponent(const gfx::Point
& point
) const override
{
40 bool ShouldDescendIntoChildForEventHandling(
42 const gfx::Point
& location
) override
{
45 bool CanFocus() override
{
46 // Ask the hosted native view's delegate because directly calling
47 // aura::Window::CanFocus() will call back into this when checking whether
49 return native_view_
&& native_view_
->delegate()
50 ? native_view_
->delegate()->CanFocus()
53 void OnCaptureLost() override
{}
54 void OnPaint(const ui::PaintContext
& context
) override
{}
55 void OnDeviceScaleFactorChanged(float device_scale_factor
) override
{}
56 void OnWindowDestroying(aura::Window
* window
) override
{}
57 void OnWindowDestroyed(aura::Window
* window
) override
{}
58 void OnWindowTargetVisibilityChanged(bool visible
) override
{}
59 bool HasHitTestMask() const override
{ return false; }
60 void GetHitTestMask(gfx::Path
* mask
) const override
{}
63 aura::Window
* native_view_
;
66 NativeViewHostAura::NativeViewHostAura(NativeViewHost
* host
)
68 clipping_window_delegate_(new ClippingWindowDelegate()),
69 clipping_window_(clipping_window_delegate_
.get()) {
70 // Set the type so descendant views (including popups) get positioned
72 clipping_window_
.SetType(ui::wm::WINDOW_TYPE_CONTROL
);
73 clipping_window_
.Init(ui::LAYER_NOT_DRAWN
);
74 clipping_window_
.set_owned_by_parent(false);
75 clipping_window_
.SetName("NativeViewHostAuraClip");
76 clipping_window_
.layer()->SetMasksToBounds(true);
77 clipping_window_
.SetProperty(views::kHostViewKey
, static_cast<View
*>(host_
));
80 NativeViewHostAura::~NativeViewHostAura() {
81 if (host_
->native_view()) {
82 host_
->native_view()->RemoveObserver(this);
83 host_
->native_view()->ClearProperty(views::kHostViewKey
);
84 host_
->native_view()->ClearProperty(aura::client::kHostWindowKey
);
85 clipping_window_
.ClearProperty(views::kHostViewKey
);
86 if (host_
->native_view()->parent() == &clipping_window_
)
87 clipping_window_
.RemoveChild(host_
->native_view());
91 ////////////////////////////////////////////////////////////////////////////////
92 // NativeViewHostAura, NativeViewHostWrapper implementation:
93 void NativeViewHostAura::AttachNativeView() {
94 clipping_window_delegate_
->set_native_view(host_
->native_view());
95 host_
->native_view()->AddObserver(this);
96 host_
->native_view()->SetProperty(views::kHostViewKey
,
97 static_cast<View
*>(host_
));
101 void NativeViewHostAura::NativeViewDetaching(bool destroyed
) {
102 clipping_window_delegate_
->set_native_view(NULL
);
103 RemoveClippingWindow();
105 host_
->native_view()->RemoveObserver(this);
106 host_
->native_view()->ClearProperty(views::kHostViewKey
);
107 host_
->native_view()->ClearProperty(aura::client::kHostWindowKey
);
108 host_
->native_view()->Hide();
109 if (host_
->native_view()->parent())
110 Widget::ReparentNativeView(host_
->native_view(), NULL
);
114 void NativeViewHostAura::AddedToWidget() {
115 if (!host_
->native_view())
119 if (host_
->IsDrawn())
120 host_
->native_view()->Show();
122 host_
->native_view()->Hide();
126 void NativeViewHostAura::RemovedFromWidget() {
127 if (host_
->native_view()) {
128 host_
->native_view()->Hide();
129 host_
->native_view()->ClearProperty(aura::client::kHostWindowKey
);
130 if (host_
->native_view()->parent())
131 host_
->native_view()->parent()->RemoveChild(host_
->native_view());
132 RemoveClippingWindow();
136 void NativeViewHostAura::InstallClip(int x
, int y
, int w
, int h
) {
138 new gfx::Rect(host_
->ConvertRectToWidget(gfx::Rect(x
, y
, w
, h
))));
141 bool NativeViewHostAura::HasInstalledClip() {
145 void NativeViewHostAura::UninstallClip() {
149 void NativeViewHostAura::ShowWidget(int x
, int y
, int w
, int h
) {
152 if (host_
->fast_resize()) {
153 gfx::Point
origin(x
, y
);
154 views::View::ConvertPointFromWidget(host_
, &origin
);
155 InstallClip(origin
.x(), origin
.y(), w
, h
);
156 width
= host_
->native_view()->bounds().width();
157 height
= host_
->native_view()->bounds().height();
159 clipping_window_
.SetBounds(clip_rect_
? *clip_rect_
160 : gfx::Rect(x
, y
, w
, h
));
162 gfx::Point clip_offset
= clipping_window_
.bounds().origin();
163 host_
->native_view()->SetBounds(
164 gfx::Rect(x
- clip_offset
.x(), y
- clip_offset
.y(), width
, height
));
165 host_
->native_view()->Show();
166 clipping_window_
.Show();
169 void NativeViewHostAura::HideWidget() {
170 host_
->native_view()->Hide();
171 clipping_window_
.Hide();
174 void NativeViewHostAura::SetFocus() {
175 aura::Window
* window
= host_
->native_view();
176 aura::client::FocusClient
* client
= aura::client::GetFocusClient(window
);
178 client
->FocusWindow(window
);
181 gfx::NativeViewAccessible
NativeViewHostAura::GetNativeViewAccessible() {
185 gfx::NativeCursor
NativeViewHostAura::GetCursor(int x
, int y
) {
186 if (host_
->native_view())
187 return host_
->native_view()->GetCursor(gfx::Point(x
, y
));
188 return gfx::kNullCursor
;
191 void NativeViewHostAura::OnWindowDestroying(aura::Window
* window
) {
192 DCHECK(window
== host_
->native_view());
193 clipping_window_delegate_
->set_native_view(NULL
);
196 void NativeViewHostAura::OnWindowDestroyed(aura::Window
* window
) {
197 DCHECK(window
== host_
->native_view());
198 host_
->NativeViewDestroyed();
202 NativeViewHostWrapper
* NativeViewHostWrapper::CreateWrapper(
203 NativeViewHost
* host
) {
204 return new NativeViewHostAura(host
);
207 void NativeViewHostAura::AddClippingWindow() {
208 RemoveClippingWindow();
210 host_
->native_view()->SetProperty(aura::client::kHostWindowKey
,
211 host_
->GetWidget()->GetNativeView());
212 Widget::ReparentNativeView(host_
->native_view(),
214 if (host_
->GetWidget()->GetNativeView()) {
215 Widget::ReparentNativeView(&clipping_window_
,
216 host_
->GetWidget()->GetNativeView());
220 void NativeViewHostAura::RemoveClippingWindow() {
221 clipping_window_
.Hide();
222 if (host_
->native_view())
223 host_
->native_view()->ClearProperty(aura::client::kHostWindowKey
);
225 if (host_
->native_view()->parent() == &clipping_window_
) {
226 if (host_
->GetWidget() && host_
->GetWidget()->GetNativeView()) {
227 Widget::ReparentNativeView(host_
->native_view(),
228 host_
->GetWidget()->GetNativeView());
230 clipping_window_
.RemoveChild(host_
->native_view());
232 host_
->native_view()->SetBounds(clipping_window_
.bounds());
234 if (clipping_window_
.parent())
235 clipping_window_
.parent()->RemoveChild(&clipping_window_
);