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

Side by Side Diff: ui/views/ime/input_method_win.cc

Issue 14698032: Make InputMethodWin TSF-aware. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Implement OnTextLayoutChanged in MockTSFBridge. Created 7 years, 7 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
« no previous file with comments | « ui/views/ime/input_method_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/views/ime/input_method_win.h" 5 #include "ui/views/ime/input_method_win.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/win/metro.h"
10 #include "ui/base/events/event.h" 11 #include "ui/base/events/event.h"
11 #include "ui/base/events/event_constants.h" 12 #include "ui/base/events/event_constants.h"
12 #include "ui/base/events/event_utils.h" 13 #include "ui/base/events/event_utils.h"
13 #include "ui/base/ime/composition_text.h" 14 #include "ui/base/ime/composition_text.h"
14 #include "ui/base/ime/input_method.h" 15 #include "ui/base/ime/input_method.h"
15 #include "ui/base/ime/text_input_client.h" 16 #include "ui/base/ime/text_input_client.h"
17 #include "ui/base/ime/win/tsf_bridge.h"
16 #include "ui/base/keycodes/keyboard_codes.h" 18 #include "ui/base/keycodes/keyboard_codes.h"
17 #include "ui/base/win/hwnd_util.h" 19 #include "ui/base/win/hwnd_util.h"
20 #include "ui/views/win/hwnd_util.h"
18 21
19 // Extra number of chars before and after selection (or composition) range which 22 // Extra number of chars before and after selection (or composition) range which
20 // is returned to IME for improving conversion accuracy. 23 // is returned to IME for improving conversion accuracy.
21 static const size_t kExtraNumberOfChars = 20; 24 static const size_t kExtraNumberOfChars = 20;
22 25
23 namespace views { 26 namespace views {
24 27
25 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate, 28 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate,
26 HWND hwnd, 29 HWND hwnd,
27 ui::InputMethod* host) 30 ui::InputMethod* host)
(...skipping 11 matching lines...) Expand all
39 } 42 }
40 43
41 void InputMethodWin::Init(Widget* widget) { 44 void InputMethodWin::Init(Widget* widget) {
42 InputMethodBase::Init(widget); 45 InputMethodBase::Init(widget);
43 46
44 // Gets the initial input locale and text direction information. 47 // Gets the initial input locale and text direction information.
45 OnInputLangChange(0, 0); 48 OnInputLangChange(0, 0);
46 } 49 }
47 50
48 void InputMethodWin::OnFocus() { 51 void InputMethodWin::OnFocus() {
49 UpdateIMEState(); 52 if (base::win::IsTSFAwareRequired()) {
53 if (GetTextInputClient()) {
54 ui::TSFBridge* tsf_bridge = ui::TSFBridge::GetInstance();
55 tsf_bridge->SetFocusedClient(hwnd_, GetTextInputClient());
56 }
57 } else {
58 // Use switch here in case we are going to add more text input types.
59 // We disable input method in password field.
60 switch (GetTextInputType()) {
61 case ui::TEXT_INPUT_TYPE_NONE:
62 case ui::TEXT_INPUT_TYPE_PASSWORD:
63 ime_input_.DisableIME(hwnd_);
64 break;
65 default:
66 ime_input_.EnableIME(hwnd_);
67 break;
68 }
69 OnTextInputTypeChanged(GetFocusedView());
70 OnCaretBoundsChanged(GetFocusedView());
71 }
50 } 72 }
51 73
52 void InputMethodWin::OnBlur() { 74 void InputMethodWin::OnBlur() {
53 ConfirmCompositionText(); 75 ConfirmCompositionText();
76 if (base::win::IsTSFAwareRequired() && GetTextInputClient())
77 ui::TSFBridge::GetInstance()->RemoveFocusedClient(GetTextInputClient());
54 } 78 }
55 79
56 void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) { 80 void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) {
57 // Handles ctrl-shift key to change text direction and layout alignment. 81 // Handles ctrl-shift key to change text direction and layout alignment.
58 if (ui::ImeInput::IsRTLKeyboardLayoutInstalled() && !IsTextInputTypeNone()) { 82 if (ui::ImeInput::IsRTLKeyboardLayoutInstalled() && !IsTextInputTypeNone()) {
59 ui::KeyboardCode code = key.key_code(); 83 ui::KeyboardCode code = key.key_code();
60 if (key.type() == ui::ET_KEY_PRESSED) { 84 if (key.type() == ui::ET_KEY_PRESSED) {
61 if (code == ui::VKEY_SHIFT) { 85 if (code == ui::VKEY_SHIFT) {
62 base::i18n::TextDirection dir; 86 base::i18n::TextDirection dir;
63 if (ui::ImeInput::IsCtrlShiftPressed(&dir)) 87 if (ui::ImeInput::IsCtrlShiftPressed(&dir))
64 pending_requested_direction_ = dir; 88 pending_requested_direction_ = dir;
65 } else if (code != ui::VKEY_CONTROL) { 89 } else if (code != ui::VKEY_CONTROL) {
66 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; 90 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION;
67 } 91 }
68 } else if (key.type() == ui::ET_KEY_RELEASED && 92 } else if (key.type() == ui::ET_KEY_RELEASED &&
69 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) && 93 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) &&
70 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) { 94 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) {
71 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment( 95 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment(
72 pending_requested_direction_); 96 pending_requested_direction_);
73 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; 97 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION;
74 } 98 }
75 } 99 }
76 100
77 DispatchKeyEventPostIME(key); 101 DispatchKeyEventPostIME(key);
78 } 102 }
79 103
80 void InputMethodWin::OnTextInputTypeChanged(View* view) { 104 void InputMethodWin::OnTextInputTypeChanged(View* view) {
81 if (IsViewFocused(view)) { 105 if (IsViewFocused(view)) {
82 ime_input_.CancelIME(hwnd_); 106 if (base::win::IsTSFAwareRequired()) {
83 UpdateIMEState(); 107 if (GetTextInputClient()) {
108 ui::TSFBridge::GetInstance()->OnTextInputTypeChanged(
109 GetTextInputClient());
110 }
111 } else {
112 ime_input_.CancelIME(hwnd_);
113 // Use switch here in case we are going to add more text input types.
114 // We disable input method in password field.
115 switch (GetTextInputType()) {
116 case ui::TEXT_INPUT_TYPE_NONE:
117 case ui::TEXT_INPUT_TYPE_PASSWORD:
118 ime_input_.DisableIME(hwnd_);
119 break;
120 default:
121 ime_input_.EnableIME(hwnd_);
122 break;
123 }
124 OnCaretBoundsChanged(GetFocusedView());
125 }
84 } 126 }
85 InputMethodBase::OnTextInputTypeChanged(view); 127 InputMethodBase::OnTextInputTypeChanged(view);
86 } 128 }
87 129
88 void InputMethodWin::OnCaretBoundsChanged(View* view) { 130 void InputMethodWin::OnCaretBoundsChanged(View* view) {
89 gfx::Rect rect; 131 if (base::win::IsTSFAwareRequired()) {
90 if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect)) 132 ui::TSFBridge::GetInstance()->OnTextLayoutChanged();
91 return; 133 } else {
92 ime_input_.UpdateCaretRect(hwnd_, rect); 134 gfx::Rect rect;
135 if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect))
136 return;
137 ime_input_.UpdateCaretRect(hwnd_, rect);
138 }
93 } 139 }
94 140
95 void InputMethodWin::CancelComposition(View* view) { 141 void InputMethodWin::CancelComposition(View* view) {
96 if (IsViewFocused(view)) 142 if (IsViewFocused(view)) {
97 ime_input_.CancelIME(hwnd_); 143 if (base::win::IsTSFAwareRequired()) {
144 ui::TSFBridge::GetInstance()->CancelComposition();
145 } else {
146 ime_input_.CancelIME(hwnd_);
147 }
148 }
98 } 149 }
99 150
100 std::string InputMethodWin::GetInputLocale() { 151 std::string InputMethodWin::GetInputLocale() {
101 return locale_; 152 return locale_;
102 } 153 }
103 154
104 base::i18n::TextDirection InputMethodWin::GetInputTextDirection() { 155 base::i18n::TextDirection InputMethodWin::GetInputTextDirection() {
105 return direction_; 156 return direction_;
106 } 157 }
107 158
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 break; 200 break;
150 } 201 }
151 return result; 202 return result;
152 } 203 }
153 204
154 void InputMethodWin::OnWillChangeFocus(View* focused_before, View* focused) { 205 void InputMethodWin::OnWillChangeFocus(View* focused_before, View* focused) {
155 ConfirmCompositionText(); 206 ConfirmCompositionText();
156 } 207 }
157 208
158 void InputMethodWin::OnDidChangeFocus(View* focused_before, View* focused) { 209 void InputMethodWin::OnDidChangeFocus(View* focused_before, View* focused) {
159 UpdateIMEState(); 210 if (base::win::IsTSFAwareRequired()) {
211 if (GetTextInputClient()) {
212 ui::TSFBridge::GetInstance()->SetFocusedClient(HWNDForView(focused),
213 GetTextInputClient());
214 }
215 } else {
216 // Use switch here in case we are going to add more text input types.
217 // We disable input method in password field.
218 switch (GetTextInputType()) {
219 case ui::TEXT_INPUT_TYPE_NONE:
220 case ui::TEXT_INPUT_TYPE_PASSWORD:
221 ime_input_.DisableIME(hwnd_);
222 break;
223 default:
224 ime_input_.EnableIME(hwnd_);
225 break;
226 }
227 OnTextInputTypeChanged(GetFocusedView());
228 OnCaretBoundsChanged(GetFocusedView());
229 }
160 } 230 }
161 231
162 void InputMethodWin::OnInputLangChange(DWORD character_set, 232 void InputMethodWin::OnInputLangChange(DWORD character_set,
163 HKL input_language_id) { 233 HKL input_language_id) {
164 active_ = ime_input_.SetInputLanguage(); 234 active_ = ime_input_.SetInputLanguage();
165 locale_ = ime_input_.GetInputLanguageName(); 235 locale_ = ime_input_.GetInputLanguageName();
166 direction_ = ime_input_.GetTextDirection(); 236 direction_ = ime_input_.GetTextDirection();
167 OnInputMethodChanged(); 237 OnInputMethodChanged();
168 } 238 }
169 239
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 342
273 // We need to send character events to the focused text input client event if 343 // We need to send character events to the focused text input client event if
274 // its text input type is ui::TEXT_INPUT_TYPE_NONE. 344 // its text input type is ui::TEXT_INPUT_TYPE_NONE.
275 if (GetTextInputClient()) { 345 if (GetTextInputClient()) {
276 GetTextInputClient()->InsertChar(static_cast<char16>(wparam), 346 GetTextInputClient()->InsertChar(static_cast<char16>(wparam),
277 ui::GetModifiersFromKeyState()); 347 ui::GetModifiersFromKeyState());
278 } 348 }
279 349
280 // Explicitly show the system menu at a good location on [Alt]+[Space]. 350 // Explicitly show the system menu at a good location on [Alt]+[Space].
281 // Note: Setting |handled| to FALSE for DefWindowProc triggering of the system 351 // Note: Setting |handled| to FALSE for DefWindowProc triggering of the system
282 // menu causes unsdesirable titlebar artifacts in the classic theme. 352 // menu causes undesirable titlebar artifacts in the classic theme.
283 if (message == WM_SYSCHAR && wparam == VK_SPACE) 353 if (message == WM_SYSCHAR && wparam == VK_SPACE)
284 ui::ShowSystemMenu(hwnd_); 354 ui::ShowSystemMenu(hwnd_);
285 355
286 return 0; 356 return 0;
287 } 357 }
288 358
289 LRESULT InputMethodWin::OnDeadChar( 359 LRESULT InputMethodWin::OnDeadChar(
290 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { 360 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) {
291 *handled = TRUE; 361 *handled = TRUE;
292 362
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 reconv->dwCompStrLen = 427 reconv->dwCompStrLen =
358 client->HasCompositionText() ? target_range.length() : 0; 428 client->HasCompositionText() ? target_range.length() : 0;
359 reconv->dwCompStrOffset = 429 reconv->dwCompStrOffset =
360 (target_range.GetMin() - text_range.start()) * sizeof(WCHAR); 430 (target_range.GetMin() - text_range.start()) * sizeof(WCHAR);
361 reconv->dwTargetStrLen = target_range.length(); 431 reconv->dwTargetStrLen = target_range.length();
362 reconv->dwTargetStrOffset = reconv->dwCompStrOffset; 432 reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
363 433
364 memcpy((char*)reconv + sizeof(RECONVERTSTRING), 434 memcpy((char*)reconv + sizeof(RECONVERTSTRING),
365 text.c_str(), len * sizeof(WCHAR)); 435 text.c_str(), len * sizeof(WCHAR));
366 436
367 // According to Microsft API document, IMR_RECONVERTSTRING and 437 // According to Microsoft API document, IMR_RECONVERTSTRING and
368 // IMR_DOCUMENTFEED should return reconv, but some applications return 438 // IMR_DOCUMENTFEED should return reconv, but some applications return
369 // need_size. 439 // need_size.
370 return reinterpret_cast<LRESULT>(reconv); 440 return reinterpret_cast<LRESULT>(reconv);
371 } 441 }
372 442
373 LRESULT InputMethodWin::OnReconvertString(RECONVERTSTRING* reconv) { 443 LRESULT InputMethodWin::OnReconvertString(RECONVERTSTRING* reconv) {
374 ui::TextInputClient* client = GetTextInputClient(); 444 ui::TextInputClient* client = GetTextInputClient();
375 if (!client) 445 if (!client)
376 return 0; 446 return 0;
377 447
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 return 0; 510 return 0;
441 511
442 char_positon->pt.x = rect.x(); 512 char_positon->pt.x = rect.x();
443 char_positon->pt.y = rect.y(); 513 char_positon->pt.y = rect.y();
444 char_positon->cLineHeight = rect.height(); 514 char_positon->cLineHeight = rect.height();
445 return 1; // returns non-zero value when succeeded. 515 return 1; // returns non-zero value when succeeded.
446 } 516 }
447 517
448 void InputMethodWin::ConfirmCompositionText() { 518 void InputMethodWin::ConfirmCompositionText() {
449 if (!IsTextInputTypeNone()) { 519 if (!IsTextInputTypeNone()) {
450 ime_input_.CleanupComposition(hwnd_); 520 if (base::win::IsTSFAwareRequired()) {
451 // Though above line should confirm the client's composition text by sending 521 // TSFBridge has not implemented ConfirmComposition yet. So here cancel
452 // a result text to us, in case the input method and the client are in 522 // the composition instead as a workaround.
453 // inconsistent states, we check the client's composition state again. 523 // TODO(ime): Implement ConfirmComposition for TSF.
454 if (GetTextInputClient()->HasCompositionText()) 524 ui::TSFBridge::GetInstance()->CancelComposition();
455 GetTextInputClient()->ConfirmCompositionText(); 525 } else {
526 ime_input_.CleanupComposition(hwnd_);
527 // Though above line should confirm the client's composition text by
528 // sending a result text to us, in case the input method and the client
529 // are in inconsistent states, we check the client's composition state
530 // again.
531 if (GetTextInputClient()->HasCompositionText())
532 GetTextInputClient()->ConfirmCompositionText();
533 }
456 } 534 }
457 } 535 }
458 536
459 void InputMethodWin::UpdateIMEState() {
460 // Use switch here in case we are going to add more text input types.
461 // We disable input method in password field.
462 switch (GetTextInputType()) {
463 case ui::TEXT_INPUT_TYPE_NONE:
464 case ui::TEXT_INPUT_TYPE_PASSWORD:
465 ime_input_.DisableIME(hwnd_);
466 break;
467 default:
468 ime_input_.EnableIME(hwnd_);
469 break;
470 }
471 }
472
473 } // namespace views 537 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/ime/input_method_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698