Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / views / cocoa / bridged_native_widget.mm
blob2a959daf9e139a6b5ccccc869ba79aa40d727c1c
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 #import "ui/views/cocoa/bridged_native_widget.h"
7 #include "base/logging.h"
8 #include "ui/base/ime/input_method.h"
9 #include "ui/base/ime/input_method_factory.h"
10 #include "ui/base/ui_base_switches_util.h"
11 #import "ui/views/cocoa/bridged_content_view.h"
12 #import "ui/views/cocoa/views_nswindow_delegate.h"
13 #include "ui/views/widget/native_widget_mac.h"
14 #include "ui/views/ime/input_method_bridge.h"
15 #include "ui/views/ime/null_input_method.h"
16 #include "ui/views/view.h"
17 #include "ui/views/widget/widget.h"
19 namespace views {
21 BridgedNativeWidget::BridgedNativeWidget(NativeWidgetMac* parent)
22     : native_widget_mac_(parent), focus_manager_(NULL) {
23   DCHECK(parent);
24   window_delegate_.reset(
25       [[ViewsNSWindowDelegate alloc] initWithBridgedNativeWidget:this]);
28 BridgedNativeWidget::~BridgedNativeWidget() {
29   RemoveOrDestroyChildren();
30   SetFocusManager(NULL);
31   SetRootView(NULL);
32   if ([window_ delegate]) {
33     // If the delegate is still set, it means OnWindowWillClose has not been
34     // called and the window is still open. Calling -[NSWindow close] will
35     // synchronously call OnWindowWillClose and notify NativeWidgetMac.
36     [window_ close];
37   }
38   DCHECK(![window_ delegate]);
41 void BridgedNativeWidget::Init(base::scoped_nsobject<NSWindow> window,
42                                const Widget::InitParams& params) {
43   DCHECK(!window_);
44   window_.swap(window);
45   [window_ setDelegate:window_delegate_];
47   if (params.parent) {
48     // Use NSWindow to manage child windows. This won't automatically close them
49     // but it will maintain relative positioning of the window layer and origin.
50     [[params.parent window] addChildWindow:window_ ordered:NSWindowAbove];
51   }
54 void BridgedNativeWidget::SetFocusManager(FocusManager* focus_manager) {
55   if (focus_manager_ == focus_manager)
56     return;
58   if (focus_manager_)
59     focus_manager_->RemoveFocusChangeListener(this);
61   if (focus_manager)
62     focus_manager->AddFocusChangeListener(this);
64   focus_manager_ = focus_manager;
67 void BridgedNativeWidget::SetRootView(views::View* view) {
68   if (view == [bridged_view_ hostedView])
69     return;
71   [bridged_view_ clearView];
72   bridged_view_.reset();
73   // Note that there can still be references to the old |bridged_view_|
74   // floating around in Cocoa libraries at this point. However, references to
75   // the old views::View will be gone, so any method calls will become no-ops.
77   if (view) {
78     bridged_view_.reset([[BridgedContentView alloc] initWithView:view]);
79     // Objective C initializers can return nil. However, if |view| is non-NULL
80     // this should be treated as an error and caught early.
81     CHECK(bridged_view_);
82   }
83   [window_ setContentView:bridged_view_];
86 void BridgedNativeWidget::OnWindowWillClose() {
87   [[window_ parentWindow] removeChildWindow:window_];
88   [window_ setDelegate:nil];
89   native_widget_mac_->OnWindowWillClose();
92 InputMethod* BridgedNativeWidget::CreateInputMethod() {
93   if (switches::IsTextInputFocusManagerEnabled())
94     return new NullInputMethod();
96   return new InputMethodBridge(this, GetHostInputMethod(), true);
99 ui::InputMethod* BridgedNativeWidget::GetHostInputMethod() {
100   if (!input_method_) {
101     // Delegate is NULL because Mac IME does not need DispatchKeyEventPostIME
102     // callbacks.
103     input_method_ = ui::CreateInputMethod(NULL, nil);
104   }
105   return input_method_.get();
108 ////////////////////////////////////////////////////////////////////////////////
109 // BridgedNativeWidget, internal::InputMethodDelegate:
111 void BridgedNativeWidget::DispatchKeyEventPostIME(const ui::KeyEvent& key) {
112   // Mac key events don't go through this, but some unit tests that use
113   // MockInputMethod do.
114   DCHECK(focus_manager_);
115   native_widget_mac_->GetWidget()->OnKeyEvent(const_cast<ui::KeyEvent*>(&key));
116   if (!key.handled())
117     focus_manager_->OnKeyEvent(key);
120 void BridgedNativeWidget::OnWillChangeFocus(View* focused_before,
121                                             View* focused_now) {
124 void BridgedNativeWidget::OnDidChangeFocus(View* focused_before,
125                                            View* focused_now) {
126   ui::TextInputClient* input_client =
127       focused_now ? focused_now->GetTextInputClient() : NULL;
128   [bridged_view_ setTextInputClient:input_client];
131 ////////////////////////////////////////////////////////////////////////////////
132 // BridgedNativeWidget, private:
134 void BridgedNativeWidget::RemoveOrDestroyChildren() {
135   // TODO(tapted): Implement unowned child windows if required.
136   base::scoped_nsobject<NSArray> child_windows(
137       [[NSArray alloc] initWithArray:[window_ childWindows]]);
138   [child_windows makeObjectsPerformSelector:@selector(close)];
141 }  // namespace views