Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: chrome/browser/ui/touch/keyboard/keyboard_manager.cc

Issue 7553016: Use text input type to control visibility of virtual keyboard (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/ui/touch/keyboard/keyboard_manager.h" 5 #include "chrome/browser/ui/touch/keyboard/keyboard_manager.h"
6 6
7 #include "chrome/browser/profiles/profile.h" 7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/browser/profiles/profile_manager.h" 8 #include "chrome/browser/profiles/profile_manager.h"
9 #include "chrome/browser/tabs/tab_strip_model.h" 9 #include "chrome/browser/tabs/tab_strip_model.h"
10 #include "chrome/browser/ui/browser_list.h" 10 #include "chrome/browser/ui/browser_list.h"
(...skipping 14 matching lines...) Expand all
25 25
26 #if defined(OS_CHROMEOS) 26 #if defined(OS_CHROMEOS)
27 #include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h" 27 #include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h"
28 #endif 28 #endif
29 29
30 namespace { 30 namespace {
31 31
32 const int kDefaultKeyboardHeight = 300; 32 const int kDefaultKeyboardHeight = 300;
33 const int kKeyboardSlideDuration = 300; // In milliseconds 33 const int kKeyboardSlideDuration = 300; // In milliseconds
34 34
35 PropertyAccessor<bool>* GetFocusedStateAccessor() {
36 static PropertyAccessor<bool> state;
37 return &state;
38 }
39
40 // Returns whether the keyboard visibility should be affected by this tab.
41 bool TabContentsCanAffectKeyboard(const TabContents* tab_contents) {
42 // There may not be a browser, e.g. for the login window. But if there is
43 // a browser, then |tab_contents| should be the active tab.
44 Browser* browser = Browser::GetBrowserForController(
45 &tab_contents->controller(), NULL);
46 return browser == NULL ||
47 (browser == BrowserList::GetLastActive() &&
48 browser->GetSelectedTabContents() == tab_contents);
49 }
50
51 } // namespace 35 } // namespace
52 36
53 // TODO(sad): Is the default profile always going to be the one we want? 37 // TODO(sad): Is the default profile always going to be the one we want?
54 38
55 KeyboardManager::KeyboardManager() 39 KeyboardManager::KeyboardManager()
56 : views::Widget::Widget(), 40 : views::Widget::Widget(),
57 dom_view_(new DOMView), 41 dom_view_(new DOMView),
58 ALLOW_THIS_IN_INITIALIZER_LIST( 42 ALLOW_THIS_IN_INITIALIZER_LIST(
59 extension_dispatcher_(ProfileManager::GetDefaultProfile(), this)), 43 extension_dispatcher_(ProfileManager::GetDefaultProfile(), this)),
60 target_(NULL), 44 target_(NULL),
(...skipping 14 matching lines...) Expand all
75 SetContentsView(dom_view_); 59 SetContentsView(dom_view_);
76 60
77 // Setup observer so the events from the keyboard can be handled. 61 // Setup observer so the events from the keyboard can be handled.
78 TabContentsObserver::Observe(dom_view_->tab_contents()); 62 TabContentsObserver::Observe(dom_view_->tab_contents());
79 63
80 // Initialize the animation. 64 // Initialize the animation.
81 animation_.reset(new ui::SlideAnimation(this)); 65 animation_.reset(new ui::SlideAnimation(this));
82 animation_->SetTweenType(ui::Tween::LINEAR); 66 animation_->SetTweenType(ui::Tween::LINEAR);
83 animation_->SetSlideDuration(kKeyboardSlideDuration); 67 animation_->SetSlideDuration(kKeyboardSlideDuration);
84 68
85 // Start listening to notifications to maintain the keyboard visibility, size 69 views::TextInputTypeTracker::GetInstance()->AddTextInputTypeObserver(this);
86 // etc.
87 registrar_.Add(this,
88 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
89 NotificationService::AllSources());
90 registrar_.Add(this,
91 content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
92 NotificationService::AllSources());
93 registrar_.Add(this,
94 content::NOTIFICATION_TAB_CONTENTS_DESTROYED,
95 NotificationService::AllSources());
96 registrar_.Add(this, 70 registrar_.Add(this,
97 chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED, 71 chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED,
98 NotificationService::AllSources()); 72 NotificationService::AllSources());
99 registrar_.Add(this, 73 registrar_.Add(this,
100 chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED, 74 chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED,
101 NotificationService::AllSources()); 75 NotificationService::AllSources());
102 registrar_.Add(this, 76 registrar_.Add(this,
103 chrome::NOTIFICATION_EDITABLE_ELEMENT_TOUCHED, 77 chrome::NOTIFICATION_EDITABLE_ELEMENT_TOUCHED,
104 NotificationService::AllSources()); 78 NotificationService::AllSources());
105 registrar_.Add(this, 79 registrar_.Add(this,
106 content::NOTIFICATION_APP_EXITING, 80 content::NOTIFICATION_APP_EXITING,
107 NotificationService::AllSources()); 81 NotificationService::AllSources());
108 82
109 #if defined(OS_CHROMEOS) 83 #if defined(OS_CHROMEOS)
110 chromeos::input_method::InputMethodManager* manager = 84 chromeos::input_method::InputMethodManager* manager =
111 chromeos::input_method::InputMethodManager::GetInstance(); 85 chromeos::input_method::InputMethodManager::GetInstance();
112 manager->AddVirtualKeyboardObserver(this); 86 manager->AddVirtualKeyboardObserver(this);
113 #endif 87 #endif
114 } 88 }
115 89
116 KeyboardManager::~KeyboardManager() { 90 KeyboardManager::~KeyboardManager() {
91 views::TextInputTypeTracker::GetInstance()->RemoveTextInputTypeObserver(this);
117 #if defined(OS_CHROMEOS) 92 #if defined(OS_CHROMEOS)
118 chromeos::input_method::InputMethodManager* manager = 93 chromeos::input_method::InputMethodManager* manager =
119 chromeos::input_method::InputMethodManager::GetInstance(); 94 chromeos::input_method::InputMethodManager::GetInstance();
120 manager->RemoveVirtualKeyboardObserver(this); 95 manager->RemoveVirtualKeyboardObserver(this);
121 #endif 96 #endif
122 // TODO(sad): Do anything else? 97 // TODO(sad): Do anything else?
123 } 98 }
124 99
125 void KeyboardManager::ShowKeyboardForWidget(views::Widget* widget) { 100 void KeyboardManager::ShowKeyboardForWidget(views::Widget* widget) {
126 target_ = widget; 101 target_ = widget;
(...skipping 28 matching lines...) Expand all
155 void KeyboardManager::AnimationProgressed(const ui::Animation* animation) { 130 void KeyboardManager::AnimationProgressed(const ui::Animation* animation) {
156 GetRootView()->SetTransform( 131 GetRootView()->SetTransform(
157 transform_->Interpolate(animation_->GetCurrentValue())); 132 transform_->Interpolate(animation_->GetCurrentValue()));
158 } 133 }
159 134
160 void KeyboardManager::AnimationEnded(const ui::Animation* animation) { 135 void KeyboardManager::AnimationEnded(const ui::Animation* animation) {
161 if (animation_->GetCurrentValue() < 0.01) 136 if (animation_->GetCurrentValue() < 0.01)
162 Widget::Hide(); 137 Widget::Hide();
163 } 138 }
164 139
165 void KeyboardManager::OnBrowserAdded(const Browser* browser) {
166 browser->tabstrip_model()->AddObserver(this);
167 }
168
169 void KeyboardManager::OnBrowserRemoved(const Browser* browser) {
170 browser->tabstrip_model()->RemoveObserver(this);
171 }
172
173 bool KeyboardManager::OnMessageReceived(const IPC::Message& message) { 140 bool KeyboardManager::OnMessageReceived(const IPC::Message& message) {
174 bool handled = true; 141 bool handled = true;
175 IPC_BEGIN_MESSAGE_MAP(KeyboardManager, message) 142 IPC_BEGIN_MESSAGE_MAP(KeyboardManager, message)
176 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) 143 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
177 IPC_MESSAGE_UNHANDLED(handled = false) 144 IPC_MESSAGE_UNHANDLED(handled = false)
178 IPC_END_MESSAGE_MAP() 145 IPC_END_MESSAGE_MAP()
179 return handled; 146 return handled;
180 } 147 }
181 148
182 void KeyboardManager::OnRequest( 149 void KeyboardManager::OnRequest(
183 const ExtensionHostMsg_Request_Params& request) { 150 const ExtensionHostMsg_Request_Params& request) {
184 extension_dispatcher_.Dispatch(request, 151 extension_dispatcher_.Dispatch(request,
185 dom_view_->tab_contents()->render_view_host()); 152 dom_view_->tab_contents()->render_view_host());
186 } 153 }
187 154
188 void KeyboardManager::ActiveTabChanged(TabContentsWrapper* old_contents, 155 void KeyboardManager::TextInputTypeChanged(ui::TextInputType type,
189 TabContentsWrapper* new_contents, 156 views::Widget *widget)
190 int index, 157 {
191 bool user_gesture) { 158 if (type == ui::TEXT_INPUT_TYPE_NONE)
192 TabContents* contents = new_contents->tab_contents(); 159 Hide();
193 if (!TabContentsCanAffectKeyboard(contents))
194 return;
195
196 // If the tab contents does not have the focus, then it should not affect the
197 // keyboard visibility.
198 views::View* view = static_cast<TabContentsViewTouch*>(contents->view());
199 views::FocusManager* fmanager = view ? view->GetFocusManager() : NULL;
200 if (!fmanager || !view->Contains(fmanager->GetFocusedView()))
201 return;
202
203 bool* editable = GetFocusedStateAccessor()->GetProperty(
204 contents->property_bag());
205 if (editable && *editable)
206 ShowKeyboardForWidget(view->GetWidget());
207 else 160 else
208 Hide(); 161 ShowKeyboardForWidget(widget);
sadrul 2011/08/02 16:15:14 Please add a TODO for using 'type'
Peng 2011/08/03 16:30:55 Done.
209 } 162 }
210 163
211 Browser* KeyboardManager::GetBrowser() { 164 Browser* KeyboardManager::GetBrowser() {
212 // TODO(sad): Find a better way. Perhaps just return NULL, and fix 165 // TODO(sad): Find a better way. Perhaps just return NULL, and fix
213 // SendKeyboardEventInputFunction::GetTopLevelWidget to somehow interact with 166 // SendKeyboardEventInputFunction::GetTopLevelWidget to somehow interact with
214 // the WM to find the top level widget? 167 // the WM to find the top level widget?
215 return BrowserList::GetLastActive(); 168 return BrowserList::GetLastActive();
216 } 169 }
217 170
218 gfx::NativeView KeyboardManager::GetNativeViewOfHost() { 171 gfx::NativeView KeyboardManager::GetNativeViewOfHost() {
(...skipping 12 matching lines...) Expand all
231 const GURL& url = virtual_keyboard.GetURLForLayout(virtual_keyboard_layout); 184 const GURL& url = virtual_keyboard.GetURLForLayout(virtual_keyboard_layout);
232 dom_view_->LoadURL(url); 185 dom_view_->LoadURL(url);
233 VLOG(1) << "VirtualKeyboardChanged: Switched to " << url.spec(); 186 VLOG(1) << "VirtualKeyboardChanged: Switched to " << url.spec();
234 } 187 }
235 #endif 188 #endif
236 189
237 void KeyboardManager::Observe(int type, 190 void KeyboardManager::Observe(int type,
238 const NotificationSource& source, 191 const NotificationSource& source,
239 const NotificationDetails& details) { 192 const NotificationDetails& details) {
240 switch (type) { 193 switch (type) {
241 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
242 // When a navigation happens, we want to hide the keyboard if the focus is
243 // in the web-page. Otherwise, the keyboard visibility should not change.
244 NavigationController* controller =
245 Source<NavigationController>(source).ptr();
246 TabContents* tab_contents = controller->tab_contents();
247 GetFocusedStateAccessor()->SetProperty(tab_contents->property_bag(),
248 false);
249 if (!TabContentsCanAffectKeyboard(tab_contents))
250 break;
251
252 TabContentsViewTouch* view =
253 static_cast<TabContentsViewTouch*>(tab_contents->view());
254 views::View* focused = view->GetFocusManager()->GetFocusedView();
255 views::TextInputClient* input =
256 focused ? focused->GetTextInputClient() : NULL;
257 // Show the keyboard if the focused view supports text-input.
258 if (input && input->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE)
259 ShowKeyboardForWidget(focused->GetWidget());
260 else
261 Hide();
262 break;
263 }
264
265 case content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE: {
266 // If the focus in the page moved to an editable field, then the keyboard
267 // should be visible, otherwise not.
268 TabContents* tab_contents = Source<TabContents>(source).ptr();
269 const bool editable = *Details<const bool>(details).ptr();
270 GetFocusedStateAccessor()->SetProperty(tab_contents->property_bag(),
271 editable);
272 if (!TabContentsCanAffectKeyboard(tab_contents))
273 break;
274
275 if (editable) {
276 TabContentsViewTouch* view =
277 static_cast<TabContentsViewTouch*>(tab_contents->view());
278 ShowKeyboardForWidget(view->GetWidget());
279 } else {
280 Hide();
281 }
282
283 break;
284 }
285
286 case content::NOTIFICATION_TAB_CONTENTS_DESTROYED: {
287 // Tab content was destroyed. Forget everything about it.
288 GetFocusedStateAccessor()->DeleteProperty(
289 Source<TabContents>(source).ptr()->property_bag());
290 break;
291 }
292
293 case chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED: { 194 case chrome::NOTIFICATION_HIDE_KEYBOARD_INVOKED: {
294 // The keyboard is hiding itself.
295 Browser* browser = BrowserList::GetLastActive();
296 if (browser) {
297 TabContents* tab_contents = browser->GetSelectedTabContents();
298 if (tab_contents) {
299 GetFocusedStateAccessor()->SetProperty(tab_contents->property_bag(),
300 false);
301 }
302 }
303
304 Hide(); 195 Hide();
305 break; 196 break;
306 } 197 }
307 198
308 case chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED: { 199 case chrome::NOTIFICATION_SET_KEYBOARD_HEIGHT_INVOKED: {
309 // The keyboard is resizing itself. 200 // The keyboard is resizing itself.
310 201
311 // TODO(penghuang) Allow extension conrtol the virtual keyboard directly 202 // TODO(penghuang) Allow extension conrtol the virtual keyboard directly
312 // instead of using Notification. 203 // instead of using Notification.
313 int height = *Details<int>(details).ptr(); 204 int height = *Details<int>(details).ptr();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 236
346 default: 237 default:
347 NOTREACHED(); 238 NOTREACHED();
348 } 239 }
349 } 240 }
350 241
351 // static 242 // static
352 KeyboardManager* KeyboardManager::GetInstance() { 243 KeyboardManager* KeyboardManager::GetInstance() {
353 return Singleton<KeyboardManager>::get(); 244 return Singleton<KeyboardManager>::get();
354 } 245 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698