OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/keyboard/keyboard_controller.h" | 5 #include "ui/keyboard/keyboard_controller.h" |
6 | 6 |
| 7 #include "base/bind.h" |
7 #include "ui/aura/layout_manager.h" | 8 #include "ui/aura/layout_manager.h" |
8 #include "ui/aura/window.h" | 9 #include "ui/aura/window.h" |
9 #include "ui/aura/window_delegate.h" | 10 #include "ui/aura/window_delegate.h" |
10 #include "ui/base/hit_test.h" | 11 #include "ui/base/hit_test.h" |
11 #include "ui/base/ime/input_method.h" | 12 #include "ui/base/ime/input_method.h" |
12 #include "ui/base/ime/text_input_client.h" | 13 #include "ui/base/ime/text_input_client.h" |
13 #include "ui/base/ime/text_input_type.h" | 14 #include "ui/base/ime/text_input_type.h" |
14 #include "ui/gfx/path.h" | 15 #include "ui/gfx/path.h" |
15 #include "ui/gfx/rect.h" | 16 #include "ui/gfx/rect.h" |
16 #include "ui/gfx/skia_util.h" | 17 #include "ui/gfx/skia_util.h" |
17 #include "ui/keyboard/keyboard_controller_observer.h" | 18 #include "ui/keyboard/keyboard_controller_observer.h" |
18 #include "ui/keyboard/keyboard_controller_proxy.h" | 19 #include "ui/keyboard/keyboard_controller_proxy.h" |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
| 23 const int kHideKeyboardDelayMs = 100; |
| 24 |
22 gfx::Rect KeyboardBoundsFromWindowBounds(const gfx::Rect& window_bounds) { | 25 gfx::Rect KeyboardBoundsFromWindowBounds(const gfx::Rect& window_bounds) { |
23 const float kKeyboardHeightRatio = 0.3f; | 26 const float kKeyboardHeightRatio = 0.3f; |
24 return gfx::Rect( | 27 return gfx::Rect( |
25 window_bounds.x(), | 28 window_bounds.x(), |
26 window_bounds.y() + window_bounds.height() * (1 - kKeyboardHeightRatio), | 29 window_bounds.y() + window_bounds.height() * (1 - kKeyboardHeightRatio), |
27 window_bounds.width(), | 30 window_bounds.width(), |
28 window_bounds.height() * kKeyboardHeightRatio); | 31 window_bounds.height() * kKeyboardHeightRatio); |
29 } | 32 } |
30 | 33 |
31 // The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. | 34 // The KeyboardWindowDelegate makes sure the keyboard-window does not get focus. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 private: | 114 private: |
112 aura::Window* container_; | 115 aura::Window* container_; |
113 aura::Window* keyboard_; | 116 aura::Window* keyboard_; |
114 | 117 |
115 DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); | 118 DISALLOW_COPY_AND_ASSIGN(KeyboardLayoutManager); |
116 }; | 119 }; |
117 | 120 |
118 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) | 121 KeyboardController::KeyboardController(KeyboardControllerProxy* proxy) |
119 : proxy_(proxy), | 122 : proxy_(proxy), |
120 container_(NULL), | 123 container_(NULL), |
121 input_method_(NULL) { | 124 input_method_(NULL), |
| 125 keyboard_visible_(false), |
| 126 weak_factory_(this) { |
122 CHECK(proxy); | 127 CHECK(proxy); |
123 input_method_ = proxy_->GetInputMethod(); | 128 input_method_ = proxy_->GetInputMethod(); |
124 input_method_->AddObserver(this); | 129 input_method_->AddObserver(this); |
125 } | 130 } |
126 | 131 |
127 KeyboardController::~KeyboardController() { | 132 KeyboardController::~KeyboardController() { |
128 if (container_) | 133 if (container_) |
129 container_->RemoveObserver(this); | 134 container_->RemoveObserver(this); |
130 if (input_method_) | 135 if (input_method_) |
131 input_method_->RemoveObserver(this); | 136 input_method_->RemoveObserver(this); |
(...skipping 27 matching lines...) Expand all Loading... |
159 void KeyboardController::OnWindowDestroying(aura::Window* window) { | 164 void KeyboardController::OnWindowDestroying(aura::Window* window) { |
160 DCHECK_EQ(container_, window); | 165 DCHECK_EQ(container_, window); |
161 container_ = NULL; | 166 container_ = NULL; |
162 } | 167 } |
163 | 168 |
164 void KeyboardController::OnTextInputStateChanged( | 169 void KeyboardController::OnTextInputStateChanged( |
165 const ui::TextInputClient* client) { | 170 const ui::TextInputClient* client) { |
166 if (!container_) | 171 if (!container_) |
167 return; | 172 return; |
168 | 173 |
169 bool was_showing = container_->IsVisible(); | 174 bool was_showing = keyboard_visible_; |
170 bool should_show = was_showing; | 175 bool should_show = was_showing; |
171 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { | 176 if (!client || client->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) { |
172 should_show = false; | 177 should_show = false; |
173 } else { | 178 } else { |
174 if (container_->children().empty()) { | 179 if (container_->children().empty()) { |
175 aura::Window* keyboard = proxy_->GetKeyboardWindow(); | 180 aura::Window* keyboard = proxy_->GetKeyboardWindow(); |
176 keyboard->Show(); | 181 keyboard->Show(); |
177 container_->AddChild(keyboard); | 182 container_->AddChild(keyboard); |
178 container_->layout_manager()->OnWindowResized(); | 183 container_->layout_manager()->OnWindowResized(); |
179 } | 184 } |
180 container_->parent()->StackChildAtTop(container_); | 185 container_->parent()->StackChildAtTop(container_); |
181 should_show = true; | 186 should_show = true; |
182 } | 187 } |
183 | 188 |
184 if (was_showing != should_show) { | 189 if (was_showing != should_show) { |
185 gfx::Rect new_bounds( | 190 if (should_show) { |
186 should_show ? container_->children()[0]->bounds() : gfx::Rect()); | 191 keyboard_visible_ = true; |
| 192 weak_factory_.InvalidateWeakPtrs(); |
| 193 if (container_->IsVisible()) |
| 194 return; |
187 | 195 |
188 FOR_EACH_OBSERVER( | 196 FOR_EACH_OBSERVER( |
189 KeyboardControllerObserver, | 197 KeyboardControllerObserver, |
190 observer_list_, | 198 observer_list_, |
191 OnKeyboardBoundsChanging(new_bounds)); | 199 OnKeyboardBoundsChanging(container_->children()[0]->bounds())); |
192 | |
193 if (should_show) | |
194 proxy_->ShowKeyboardContainer(container_); | 200 proxy_->ShowKeyboardContainer(container_); |
195 else | 201 } else { |
196 proxy_->HideKeyboardContainer(container_); | 202 keyboard_visible_ = false; |
| 203 base::MessageLoop::current()->PostDelayedTask( |
| 204 FROM_HERE, |
| 205 base::Bind(&KeyboardController::HideKeyboard, |
| 206 weak_factory_.GetWeakPtr()), |
| 207 base::TimeDelta::FromMilliseconds(kHideKeyboardDelayMs)); |
| 208 } |
197 } | 209 } |
198 | |
199 // TODO(bryeung): whenever the TextInputClient changes we need to notify the | 210 // TODO(bryeung): whenever the TextInputClient changes we need to notify the |
200 // keyboard (with the TextInputType) so that it can reset it's state (e.g. | 211 // keyboard (with the TextInputType) so that it can reset it's state (e.g. |
201 // abandon compositions in progress) | 212 // abandon compositions in progress) |
202 } | 213 } |
203 | 214 |
204 void KeyboardController::OnInputMethodDestroyed( | 215 void KeyboardController::OnInputMethodDestroyed( |
205 const ui::InputMethod* input_method) { | 216 const ui::InputMethod* input_method) { |
206 DCHECK_EQ(input_method_, input_method); | 217 DCHECK_EQ(input_method_, input_method); |
207 input_method_ = NULL; | 218 input_method_ = NULL; |
208 } | 219 } |
209 | 220 |
| 221 void KeyboardController::HideKeyboard() { |
| 222 FOR_EACH_OBSERVER(KeyboardControllerObserver, |
| 223 observer_list_, |
| 224 OnKeyboardBoundsChanging(gfx::Rect())); |
| 225 proxy_->HideKeyboardContainer(container_); |
| 226 } |
| 227 |
| 228 bool KeyboardController::WillHideKeyboard() const { |
| 229 return weak_factory_.HasWeakPtrs(); |
| 230 } |
| 231 |
210 } // namespace keyboard | 232 } // namespace keyboard |
OLD | NEW |