Chromium Code Reviews| 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/base/ime/input_method_win.h" | 5 #include "ui/base/ime/input_method_win.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/profiler/scoped_tracker.h" | 9 #include "base/profiler/scoped_tracker.h" |
| 10 #include "ui/base/ime/text_input_client.h" | 10 #include "ui/base/ime/text_input_client.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 } // namespace | 26 } // namespace |
| 27 | 27 |
| 28 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate, | 28 InputMethodWin::InputMethodWin(internal::InputMethodDelegate* delegate, |
| 29 HWND toplevel_window_handle) | 29 HWND toplevel_window_handle) |
| 30 : toplevel_window_handle_(toplevel_window_handle), | 30 : toplevel_window_handle_(toplevel_window_handle), |
| 31 pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION), | 31 pending_requested_direction_(base::i18n::UNKNOWN_DIRECTION), |
| 32 accept_carriage_return_(false), | 32 accept_carriage_return_(false), |
| 33 enabled_(false), | 33 enabled_(false), |
| 34 is_candidate_popup_open_(false), | 34 is_candidate_popup_open_(false), |
| 35 composing_window_handle_(NULL), | 35 composing_window_handle_(NULL), |
| 36 suppress_next_char_(false), | 36 suppress_next_char_(false) { |
| 37 destroyed_ptr_(nullptr) { | |
| 38 SetDelegate(delegate); | 37 SetDelegate(delegate); |
| 39 } | 38 } |
| 40 | 39 |
| 41 InputMethodWin::~InputMethodWin() { | |
| 42 if (destroyed_ptr_) | |
| 43 *destroyed_ptr_ = true; | |
| 44 } | |
| 45 | |
| 46 void InputMethodWin::OnFocus() { | 40 void InputMethodWin::OnFocus() { |
| 47 InputMethodBase::OnFocus(); | 41 InputMethodBase::OnFocus(); |
| 48 if (GetTextInputClient()) | 42 if (GetTextInputClient()) |
| 49 UpdateIMEState(); | 43 UpdateIMEState(); |
| 50 } | 44 } |
| 51 | 45 |
| 52 void InputMethodWin::OnBlur() { | 46 void InputMethodWin::OnBlur() { |
| 53 ConfirmCompositionText(); | 47 ConfirmCompositionText(); |
| 54 // Gets the focused text input client before calling parent's OnBlur() because | 48 // Gets the focused text input client before calling parent's OnBlur() because |
| 55 // it will cause GetTextInputClient() returns NULL. | 49 // it will cause GetTextInputClient() returns NULL. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 97 break; | 91 break; |
| 98 default: | 92 default: |
| 99 NOTREACHED() << "Unknown IME message:" << event.message; | 93 NOTREACHED() << "Unknown IME message:" << event.message; |
| 100 break; | 94 break; |
| 101 } | 95 } |
| 102 if (result) | 96 if (result) |
| 103 *result = original_result; | 97 *result = original_result; |
| 104 return !!handled; | 98 return !!handled; |
| 105 } | 99 } |
| 106 | 100 |
| 107 bool InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& event) { | 101 void InputMethodWin::DispatchKeyEvent(ui::KeyEvent* event) { |
| 108 if (!event.HasNativeEvent()) | 102 if (!event->HasNativeEvent()) |
| 109 return DispatchFabricatedKeyEvent(event); | 103 return DispatchFabricatedKeyEvent(event); |
|
James Su
2015/07/31 11:43:58
This looks weird, as this method doesn't have retu
Shu Chen
2015/08/03 01:44:47
Done.
| |
| 110 | 104 |
| 111 const base::NativeEvent& native_key_event = event.native_event(); | 105 const base::NativeEvent& native_key_event = event->native_event(); |
| 112 if (native_key_event.message == WM_CHAR) { | 106 if (native_key_event.message == WM_CHAR) { |
| 113 BOOL handled; | 107 BOOL handled; |
| 114 OnChar(native_key_event.hwnd, native_key_event.message, | 108 OnChar(native_key_event.hwnd, native_key_event.message, |
| 115 native_key_event.wParam, native_key_event.lParam, &handled); | 109 native_key_event.wParam, native_key_event.lParam, &handled); |
| 116 return !!handled; // Don't send WM_CHAR for post event processing. | 110 if (handled) |
| 111 event->StopPropagation(); | |
| 112 return; | |
| 117 } | 113 } |
| 118 // Handles ctrl-shift key to change text direction and layout alignment. | 114 // Handles ctrl-shift key to change text direction and layout alignment. |
| 119 if (ui::IMM32Manager::IsRTLKeyboardLayoutInstalled() && | 115 if (ui::IMM32Manager::IsRTLKeyboardLayoutInstalled() && |
| 120 !IsTextInputTypeNone()) { | 116 !IsTextInputTypeNone()) { |
| 121 // TODO: shouldn't need to generate a KeyEvent here. | 117 // TODO: shouldn't need to generate a KeyEvent here. |
| 122 const ui::KeyEvent key(native_key_event); | 118 const ui::KeyEvent key(native_key_event); |
| 123 ui::KeyboardCode code = key.key_code(); | 119 ui::KeyboardCode code = key.key_code(); |
| 124 if (key.type() == ui::ET_KEY_PRESSED) { | 120 if (key.type() == ui::ET_KEY_PRESSED) { |
| 125 if (code == ui::VKEY_SHIFT) { | 121 if (code == ui::VKEY_SHIFT) { |
| 126 base::i18n::TextDirection dir; | 122 base::i18n::TextDirection dir; |
| 127 if (ui::IMM32Manager::IsCtrlShiftPressed(&dir)) | 123 if (ui::IMM32Manager::IsCtrlShiftPressed(&dir)) |
| 128 pending_requested_direction_ = dir; | 124 pending_requested_direction_ = dir; |
| 129 } else if (code != ui::VKEY_CONTROL) { | 125 } else if (code != ui::VKEY_CONTROL) { |
| 130 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; | 126 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 131 } | 127 } |
| 132 } else if (key.type() == ui::ET_KEY_RELEASED && | 128 } else if (key.type() == ui::ET_KEY_RELEASED && |
| 133 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) && | 129 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) && |
| 134 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) { | 130 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) { |
| 135 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment( | 131 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment( |
| 136 pending_requested_direction_); | 132 pending_requested_direction_); |
| 137 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; | 133 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; |
| 138 } | 134 } |
| 139 } | 135 } |
| 140 | 136 |
| 141 bool destroyed = false; | 137 ui::EventDispatchDetails details = DispatchKeyEventPostIME(event); |
| 142 base::AutoReset<bool*> auto_reset(&destroyed_ptr_, &destroyed); | 138 if (!details.dispatcher_destroyed) |
| 143 bool handled = DispatchKeyEventPostIME(event); | 139 suppress_next_char_ = event->stopped_propagation(); |
| 144 if (destroyed) | |
| 145 return true; | |
| 146 suppress_next_char_ = handled; | |
| 147 return handled; | |
| 148 } | 140 } |
| 149 | 141 |
| 150 void InputMethodWin::OnTextInputTypeChanged(const TextInputClient* client) { | 142 void InputMethodWin::OnTextInputTypeChanged(const TextInputClient* client) { |
| 151 if (!IsTextInputClientFocused(client) || !IsWindowFocused(client)) | 143 if (!IsTextInputClientFocused(client) || !IsWindowFocused(client)) |
| 152 return; | 144 return; |
| 153 imm32_manager_.CancelIME(toplevel_window_handle_); | 145 imm32_manager_.CancelIME(toplevel_window_handle_); |
| 154 UpdateIMEState(); | 146 UpdateIMEState(); |
| 155 } | 147 } |
| 156 | 148 |
| 157 void InputMethodWin::OnCaretBoundsChanged(const TextInputClient* client) { | 149 void InputMethodWin::OnCaretBoundsChanged(const TextInputClient* client) { |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 584 return false; | 576 return false; |
| 585 // When Aura is enabled, |attached_window_handle| should always be a top-level | 577 // When Aura is enabled, |attached_window_handle| should always be a top-level |
| 586 // window. So we can safely assume that |attached_window_handle| is ready for | 578 // window. So we can safely assume that |attached_window_handle| is ready for |
| 587 // receiving keyboard input as long as it is an active window. This works well | 579 // receiving keyboard input as long as it is an active window. This works well |
| 588 // even when the |attached_window_handle| becomes active but has not received | 580 // even when the |attached_window_handle| becomes active but has not received |
| 589 // WM_FOCUS yet. | 581 // WM_FOCUS yet. |
| 590 return toplevel_window_handle_ && | 582 return toplevel_window_handle_ && |
| 591 GetActiveWindow() == toplevel_window_handle_; | 583 GetActiveWindow() == toplevel_window_handle_; |
| 592 } | 584 } |
| 593 | 585 |
| 594 bool InputMethodWin::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) { | 586 void InputMethodWin::DispatchFabricatedKeyEvent(ui::KeyEvent* event) { |
| 595 if (event.is_char()) { | 587 if (event->is_char()) { |
| 596 if (suppress_next_char_) { | 588 if (suppress_next_char_) { |
| 597 suppress_next_char_ = false; | 589 suppress_next_char_ = false; |
| 598 return true; | 590 return; |
| 599 } | 591 } |
| 600 if (GetTextInputClient()) { | 592 if (GetTextInputClient()) { |
| 601 GetTextInputClient()->InsertChar( | 593 GetTextInputClient()->InsertChar( |
| 602 static_cast<base::char16>(event.key_code()), | 594 static_cast<base::char16>(event->key_code()), |
| 603 ui::GetModifiersFromKeyState()); | 595 ui::GetModifiersFromKeyState()); |
| 604 return true; | 596 return; |
| 605 } | 597 } |
| 606 } | 598 } |
| 607 return DispatchKeyEventPostIME(event); | 599 ignore_result(DispatchKeyEventPostIME(event)); |
| 608 } | 600 } |
| 609 | 601 |
| 610 void InputMethodWin::ConfirmCompositionText() { | 602 void InputMethodWin::ConfirmCompositionText() { |
| 611 if (composing_window_handle_) | 603 if (composing_window_handle_) |
| 612 imm32_manager_.CleanupComposition(composing_window_handle_); | 604 imm32_manager_.CleanupComposition(composing_window_handle_); |
| 613 | 605 |
| 614 if (!IsTextInputTypeNone()) { | 606 if (!IsTextInputTypeNone()) { |
| 615 // Though above line should confirm the client's composition text by sending | 607 // Though above line should confirm the client's composition text by sending |
| 616 // a result text to us, in case the input method and the client are in | 608 // a result text to us, in case the input method and the client are in |
| 617 // inconsistent states, we check the client's composition state again. | 609 // inconsistent states, we check the client's composition state again. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 637 enabled_ = true; | 629 enabled_ = true; |
| 638 break; | 630 break; |
| 639 } | 631 } |
| 640 | 632 |
| 641 imm32_manager_.SetTextInputMode(window_handle, text_input_mode); | 633 imm32_manager_.SetTextInputMode(window_handle, text_input_mode); |
| 642 tsf_inputscope::SetInputScopeForTsfUnawareWindow( | 634 tsf_inputscope::SetInputScopeForTsfUnawareWindow( |
| 643 window_handle, text_input_type, text_input_mode); | 635 window_handle, text_input_type, text_input_mode); |
| 644 } | 636 } |
| 645 | 637 |
| 646 } // namespace ui | 638 } // namespace ui |
| OLD | NEW |