[MacViews] Fix WebViewInteractiveUiTest.TextInputClientIsUpToDate.
[chromium-blink-merge.git] / ui / views / controls / native / native_view_host_mac.mm
blob2ef7874f1e9dcb680881dc0c253cf26d3d57bbd0
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 #include "base/logging.h"
10 #include "base/mac/foundation_util.h"
11 #import "ui/views/cocoa/bridged_content_view.h"
12 #include "ui/views/controls/native/native_view_host.h"
13 #include "ui/views/widget/widget.h"
15 namespace views {
16 namespace {
18 // Reparents |native_view| to be a child of the native content view of
19 // |new_parent|.
20 void ReparentNSView(NSView* native_view, Widget* new_parent) {
21   DCHECK(native_view);
22   // Mac's NativeViewHost has no support for hosting its own child widgets.
23   // This check is probably overly restrictive, since the Widget containing the
24   // NativeViewHost _is_ allowed child Widgets. However, we don't know yet
25   // whether those child Widgets need to be distinguished from Widgets that code
26   // might want to associate with the hosted NSView instead.
27   {
28     Widget::Widgets child_widgets;
29     Widget::GetAllChildWidgets(native_view, &child_widgets);
30     CHECK_GE(1u, child_widgets.size());  // 1 (itself) or 0 if detached.
31   }
33   if (!new_parent) {
34     [native_view removeFromSuperview];
35     return;
36   }
38   BridgedContentView* new_superview =
39       base::mac::ObjCCastStrict<BridgedContentView>(
40           new_parent->GetNativeView());
41   DCHECK(new_superview);
42   [new_superview addSubview:native_view];
45 }  // namespace
47 NativeViewHostMac::NativeViewHostMac(NativeViewHost* host) : host_(host) {
50 NativeViewHostMac::~NativeViewHostMac() {
53 ////////////////////////////////////////////////////////////////////////////////
54 // NativeViewHostMac, NativeViewHostWrapper implementation:
56 void NativeViewHostMac::AttachNativeView() {
57   DCHECK(host_->native_view());
58   DCHECK(!native_view_);
59   native_view_.reset([host_->native_view() retain]);
60   ReparentNSView(host_->native_view(), host_->GetWidget());
63 void NativeViewHostMac::NativeViewDetaching(bool destroyed) {
64   // |destroyed| is only true if this class calls host_->NativeViewDestroyed().
65   // Aura does this after observing an aura OnWindowDestroying, but NSViews
66   // are reference counted so there isn't a reliable signal. Instead, a
67   // reference is retained until the NativeViewHost is detached.
68   DCHECK(!destroyed);
69   // |native_view_| can be nil here if RemovedFromWidget() is called before
70   // NativeViewHost::Detach().
71   DCHECK(!native_view_ || native_view_ == host_->native_view());
72   [host_->native_view() setHidden:YES];
73   ReparentNSView(host_->native_view(), NULL);
74   native_view_.reset();
77 void NativeViewHostMac::AddedToWidget() {
78   if (!host_->native_view())
79     return;
81   AttachNativeView();
82   host_->Layout();
85 void NativeViewHostMac::RemovedFromWidget() {
86   if (!host_->native_view())
87     return;
89   NativeViewDetaching(false);
92 void NativeViewHostMac::InstallClip(int x, int y, int w, int h) {
93   NOTIMPLEMENTED();
96 bool NativeViewHostMac::HasInstalledClip() {
97   return false;
100 void NativeViewHostMac::UninstallClip() {
101   NOTIMPLEMENTED();
104 void NativeViewHostMac::ShowWidget(int x, int y, int w, int h) {
105   if (host_->fast_resize())
106     NOTIMPLEMENTED();
108   // Coordinates will be from the top left of the parent Widget. The NativeView
109   // is already in the same NSWindow, so just flip to get Cooca coordinates and
110   // then convert to the containing view.
111   NSRect window_rect = NSMakeRect(
112       x,
113       host_->GetWidget()->GetClientAreaBoundsInScreen().height() - y - h,
114       w,
115       h);
117   // Convert window coordinates to the hosted view's superview, since that's how
118   // coordinates of the hosted view's frame is based.
119   NSRect container_rect =
120       [[host_->native_view() superview] convertRect:window_rect fromView:nil];
121   [host_->native_view() setFrame:container_rect];
122   [host_->native_view() setHidden:NO];
125 void NativeViewHostMac::HideWidget() {
126   [host_->native_view() setHidden:YES];
129 void NativeViewHostMac::SetFocus() {
130   if ([host_->native_view() acceptsFirstResponder])
131     [[host_->native_view() window] makeFirstResponder:host_->native_view()];
134 gfx::NativeViewAccessible NativeViewHostMac::GetNativeViewAccessible() {
135   return NULL;
138 gfx::NativeCursor NativeViewHostMac::GetCursor(int x, int y) {
139   NOTIMPLEMENTED();
140   return gfx::kNullCursor;
143 // static
144 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
145     NativeViewHost* host) {
146   return new NativeViewHostMac(host);
149 }  // namespace views