OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |