| OLD | NEW |
| 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 "ui/base/events/event.h" | 10 #include "ui/base/events/event.h" |
| 11 #include "ui/base/events/event_constants.h" | 11 #include "ui/base/events/event_constants.h" |
| 12 #include "ui/base/ime/composition_text.h" | 12 #include "ui/base/ime/composition_text.h" |
| 13 #include "ui/base/ime/text_input_client.h" | 13 #include "ui/base/ime/text_input_client.h" |
| 14 #include "ui/base/keycodes/keyboard_codes.h" | 14 #include "ui/base/keycodes/keyboard_codes.h" |
| 15 | 15 |
| 16 // Extra number of chars before and after selection (or composition) range which | 16 // Extra number of chars before and after selection (or composition) range which |
| 17 // is returned to IME for improving conversion accuracy. | 17 // is returned to IME for improving conversion accuracy. |
| 18 static const size_t kExtraNumberOfChars = 20; | 18 static const size_t kExtraNumberOfChars = 20; |
| 19 | 19 |
| 20 namespace views { | 20 namespace views { |
| 21 | 21 |
| 22 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate) | 22 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate, |
| 23 : active_(false), | 23 HWND hwnd) |
| 24 : hwnd_(hwnd), |
| 25 active_(false), |
| 24 direction_(base::i18n::UNKNOWN_DIRECTION), | 26 direction_(base::i18n::UNKNOWN_DIRECTION), |
| 25 pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION) { | 27 pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION) { |
| 26 set_delegate(delegate); | 28 set_delegate(delegate); |
| 27 } | 29 } |
| 28 | 30 |
| 29 InputMethodWin::~InputMethodWin() { | 31 InputMethodWin::~InputMethodWin() { |
| 30 if (widget()) | 32 if (widget()) |
| 31 ime_input_.DisableIME(hwnd()); | 33 ime_input_.DisableIME(hwnd_); |
| 32 } | 34 } |
| 33 | 35 |
| 34 void InputMethodWin::Init(Widget* widget) { | 36 void InputMethodWin::Init(Widget* widget) { |
| 35 // Gets the initial input locale and text direction information. | 37 // Gets the initial input locale and text direction information. |
| 36 OnInputLangChange(0, 0); | 38 OnInputLangChange(0, 0); |
| 37 | 39 |
| 38 InputMethodBase::Init(widget); | 40 InputMethodBase::Init(widget); |
| 39 } | 41 } |
| 40 | 42 |
| 41 void InputMethodWin::OnFocus() { | 43 void InputMethodWin::OnFocus() { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 69 pending_requested_direction_); | 71 pending_requested_direction_); |
| 70 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; | 72 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 71 } | 73 } |
| 72 } | 74 } |
| 73 | 75 |
| 74 DispatchKeyEventPostIME(key); | 76 DispatchKeyEventPostIME(key); |
| 75 } | 77 } |
| 76 | 78 |
| 77 void InputMethodWin::OnTextInputTypeChanged(View* view) { | 79 void InputMethodWin::OnTextInputTypeChanged(View* view) { |
| 78 if (IsViewFocused(view)) { | 80 if (IsViewFocused(view)) { |
| 79 ime_input_.CancelIME(hwnd()); | 81 ime_input_.CancelIME(hwnd_); |
| 80 UpdateIMEState(); | 82 UpdateIMEState(); |
| 81 } | 83 } |
| 82 InputMethodBase::OnTextInputTypeChanged(view); | 84 InputMethodBase::OnTextInputTypeChanged(view); |
| 83 } | 85 } |
| 84 | 86 |
| 85 void InputMethodWin::OnCaretBoundsChanged(View* view) { | 87 void InputMethodWin::OnCaretBoundsChanged(View* view) { |
| 86 gfx::Rect rect; | 88 gfx::Rect rect; |
| 87 if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect)) | 89 if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect)) |
| 88 return; | 90 return; |
| 89 ime_input_.UpdateCaretRect(hwnd(), rect); | 91 ime_input_.UpdateCaretRect(hwnd_, rect); |
| 90 } | 92 } |
| 91 | 93 |
| 92 void InputMethodWin::CancelComposition(View* view) { | 94 void InputMethodWin::CancelComposition(View* view) { |
| 93 if (IsViewFocused(view)) | 95 if (IsViewFocused(view)) |
| 94 ime_input_.CancelIME(hwnd()); | 96 ime_input_.CancelIME(hwnd_); |
| 95 } | 97 } |
| 96 | 98 |
| 97 std::string InputMethodWin::GetInputLocale() { | 99 std::string InputMethodWin::GetInputLocale() { |
| 98 return locale_; | 100 return locale_; |
| 99 } | 101 } |
| 100 | 102 |
| 101 base::i18n::TextDirection InputMethodWin::GetInputTextDirection() { | 103 base::i18n::TextDirection InputMethodWin::GetInputTextDirection() { |
| 102 return direction_; | 104 return direction_; |
| 103 } | 105 } |
| 104 | 106 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 active_ = ime_input_.SetInputLanguage(); | 155 active_ = ime_input_.SetInputLanguage(); |
| 154 locale_ = ime_input_.GetInputLanguageName(); | 156 locale_ = ime_input_.GetInputLanguageName(); |
| 155 direction_ = ime_input_.GetTextDirection(); | 157 direction_ = ime_input_.GetTextDirection(); |
| 156 OnInputMethodChanged(); | 158 OnInputMethodChanged(); |
| 157 } | 159 } |
| 158 | 160 |
| 159 LRESULT InputMethodWin::OnImeSetContext( | 161 LRESULT InputMethodWin::OnImeSetContext( |
| 160 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | 162 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
| 161 active_ = (wparam == TRUE); | 163 active_ = (wparam == TRUE); |
| 162 if (active_) | 164 if (active_) |
| 163 ime_input_.CreateImeWindow(hwnd()); | 165 ime_input_.CreateImeWindow(hwnd_); |
| 164 | 166 |
| 165 OnInputMethodChanged(); | 167 OnInputMethodChanged(); |
| 166 return ime_input_.SetImeWindowStyle(hwnd(), message, wparam, lparam, handled); | 168 return ime_input_.SetImeWindowStyle(hwnd_, message, wparam, lparam, handled); |
| 167 } | 169 } |
| 168 | 170 |
| 169 LRESULT InputMethodWin::OnImeStartComposition( | 171 LRESULT InputMethodWin::OnImeStartComposition( |
| 170 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | 172 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
| 171 // We have to prevent WTL from calling ::DefWindowProc() because the function | 173 // We have to prevent WTL from calling ::DefWindowProc() because the function |
| 172 // calls ::ImmSetCompositionWindow() and ::ImmSetCandidateWindow() to | 174 // calls ::ImmSetCompositionWindow() and ::ImmSetCandidateWindow() to |
| 173 // over-write the position of IME windows. | 175 // over-write the position of IME windows. |
| 174 *handled = TRUE; | 176 *handled = TRUE; |
| 175 | 177 |
| 176 if (IsTextInputTypeNone()) | 178 if (IsTextInputTypeNone()) |
| 177 return 0; | 179 return 0; |
| 178 | 180 |
| 179 // Reset the composition status and create IME windows. | 181 // Reset the composition status and create IME windows. |
| 180 ime_input_.CreateImeWindow(hwnd()); | 182 ime_input_.CreateImeWindow(hwnd_); |
| 181 ime_input_.ResetComposition(hwnd()); | 183 ime_input_.ResetComposition(hwnd_); |
| 182 return 0; | 184 return 0; |
| 183 } | 185 } |
| 184 | 186 |
| 185 LRESULT InputMethodWin::OnImeComposition( | 187 LRESULT InputMethodWin::OnImeComposition( |
| 186 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | 188 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
| 187 // We have to prevent WTL from calling ::DefWindowProc() because we do not | 189 // We have to prevent WTL from calling ::DefWindowProc() because we do not |
| 188 // want for the IMM (Input Method Manager) to send WM_IME_CHAR messages. | 190 // want for the IMM (Input Method Manager) to send WM_IME_CHAR messages. |
| 189 *handled = TRUE; | 191 *handled = TRUE; |
| 190 | 192 |
| 191 if (IsTextInputTypeNone()) | 193 if (IsTextInputTypeNone()) |
| 192 return 0; | 194 return 0; |
| 193 | 195 |
| 194 // At first, update the position of the IME window. | 196 // At first, update the position of the IME window. |
| 195 ime_input_.UpdateImeWindow(hwnd()); | 197 ime_input_.UpdateImeWindow(hwnd_); |
| 196 | 198 |
| 197 // Retrieve the result string and its attributes of the ongoing composition | 199 // Retrieve the result string and its attributes of the ongoing composition |
| 198 // and send it to a renderer process. | 200 // and send it to a renderer process. |
| 199 ui::CompositionText composition; | 201 ui::CompositionText composition; |
| 200 if (ime_input_.GetResult(hwnd(), lparam, &composition.text)) { | 202 if (ime_input_.GetResult(hwnd_, lparam, &composition.text)) { |
| 201 GetTextInputClient()->InsertText(composition.text); | 203 GetTextInputClient()->InsertText(composition.text); |
| 202 ime_input_.ResetComposition(hwnd()); | 204 ime_input_.ResetComposition(hwnd_); |
| 203 // Fall though and try reading the composition string. | 205 // Fall though and try reading the composition string. |
| 204 // Japanese IMEs send a message containing both GCS_RESULTSTR and | 206 // Japanese IMEs send a message containing both GCS_RESULTSTR and |
| 205 // GCS_COMPSTR, which means an ongoing composition has been finished | 207 // GCS_COMPSTR, which means an ongoing composition has been finished |
| 206 // by the start of another composition. | 208 // by the start of another composition. |
| 207 } | 209 } |
| 208 // Retrieve the composition string and its attributes of the ongoing | 210 // Retrieve the composition string and its attributes of the ongoing |
| 209 // composition and send it to a renderer process. | 211 // composition and send it to a renderer process. |
| 210 if (ime_input_.GetComposition(hwnd(), lparam, &composition)) | 212 if (ime_input_.GetComposition(hwnd_, lparam, &composition)) |
| 211 GetTextInputClient()->SetCompositionText(composition); | 213 GetTextInputClient()->SetCompositionText(composition); |
| 212 | 214 |
| 213 return 0; | 215 return 0; |
| 214 } | 216 } |
| 215 | 217 |
| 216 LRESULT InputMethodWin::OnImeEndComposition( | 218 LRESULT InputMethodWin::OnImeEndComposition( |
| 217 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | 219 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
| 218 // Let WTL call ::DefWindowProc() and release its resources. | 220 // Let WTL call ::DefWindowProc() and release its resources. |
| 219 *handled = FALSE; | 221 *handled = FALSE; |
| 220 | 222 |
| 221 if (IsTextInputTypeNone()) | 223 if (IsTextInputTypeNone()) |
| 222 return 0; | 224 return 0; |
| 223 | 225 |
| 224 if (GetTextInputClient()->HasCompositionText()) | 226 if (GetTextInputClient()->HasCompositionText()) |
| 225 GetTextInputClient()->ClearCompositionText(); | 227 GetTextInputClient()->ClearCompositionText(); |
| 226 | 228 |
| 227 ime_input_.ResetComposition(hwnd()); | 229 ime_input_.ResetComposition(hwnd_); |
| 228 ime_input_.DestroyImeWindow(hwnd()); | 230 ime_input_.DestroyImeWindow(hwnd_); |
| 229 return 0; | 231 return 0; |
| 230 } | 232 } |
| 231 | 233 |
| 232 LRESULT InputMethodWin::OnImeRequest( | 234 LRESULT InputMethodWin::OnImeRequest( |
| 233 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { | 235 UINT message, WPARAM wparam, LPARAM lparam, BOOL* handled) { |
| 234 *handled = FALSE; | 236 *handled = FALSE; |
| 235 | 237 |
| 236 // Should not receive WM_IME_REQUEST message, if IME is disabled. | 238 // Should not receive WM_IME_REQUEST message, if IME is disabled. |
| 237 const ui::TextInputType type = GetTextInputType(); | 239 const ui::TextInputType type = GetTextInputType(); |
| 238 if (type == ui::TEXT_INPUT_TYPE_NONE || | 240 if (type == ui::TEXT_INPUT_TYPE_NONE || |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 text.c_str(), len * sizeof(WCHAR)); | 398 text.c_str(), len * sizeof(WCHAR)); |
| 397 | 399 |
| 398 // According to Microsft API document, IMR_RECONVERTSTRING and | 400 // According to Microsft API document, IMR_RECONVERTSTRING and |
| 399 // IMR_DOCUMENTFEED should return reconv, but some applications return | 401 // IMR_DOCUMENTFEED should return reconv, but some applications return |
| 400 // need_size. | 402 // need_size. |
| 401 return reinterpret_cast<LRESULT>(reconv); | 403 return reinterpret_cast<LRESULT>(reconv); |
| 402 } | 404 } |
| 403 | 405 |
| 404 void InputMethodWin::ConfirmCompositionText() { | 406 void InputMethodWin::ConfirmCompositionText() { |
| 405 if (!IsTextInputTypeNone()) { | 407 if (!IsTextInputTypeNone()) { |
| 406 ime_input_.CleanupComposition(hwnd()); | 408 ime_input_.CleanupComposition(hwnd_); |
| 407 // Though above line should confirm the client's composition text by sending | 409 // Though above line should confirm the client's composition text by sending |
| 408 // a result text to us, in case the input method and the client are in | 410 // a result text to us, in case the input method and the client are in |
| 409 // inconsistent states, we check the client's composition state again. | 411 // inconsistent states, we check the client's composition state again. |
| 410 if (GetTextInputClient()->HasCompositionText()) | 412 if (GetTextInputClient()->HasCompositionText()) |
| 411 GetTextInputClient()->ConfirmCompositionText(); | 413 GetTextInputClient()->ConfirmCompositionText(); |
| 412 } | 414 } |
| 413 } | 415 } |
| 414 | 416 |
| 415 void InputMethodWin::UpdateIMEState() { | 417 void InputMethodWin::UpdateIMEState() { |
| 416 // Use switch here in case we are going to add more text input types. | 418 // Use switch here in case we are going to add more text input types. |
| 417 // We disable input method in password field. | 419 // We disable input method in password field. |
| 418 switch (GetTextInputType()) { | 420 switch (GetTextInputType()) { |
| 419 case ui::TEXT_INPUT_TYPE_NONE: | 421 case ui::TEXT_INPUT_TYPE_NONE: |
| 420 case ui::TEXT_INPUT_TYPE_PASSWORD: | 422 case ui::TEXT_INPUT_TYPE_PASSWORD: |
| 421 ime_input_.DisableIME(hwnd()); | 423 ime_input_.DisableIME(hwnd_); |
| 422 break; | 424 break; |
| 423 default: | 425 default: |
| 424 ime_input_.EnableIME(hwnd()); | 426 ime_input_.EnableIME(hwnd_); |
| 425 break; | 427 break; |
| 426 } | 428 } |
| 427 } | 429 } |
| 428 | 430 |
| 429 } // namespace views | 431 } // namespace views |
| OLD | NEW |