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 DispatchFabricatedKeyEvent(event); |
| 104 return; |
| 105 } |
110 | 106 |
111 const base::NativeEvent& native_key_event = event.native_event(); | 107 const base::NativeEvent& native_key_event = event->native_event(); |
112 if (native_key_event.message == WM_CHAR) { | 108 if (native_key_event.message == WM_CHAR) { |
113 BOOL handled; | 109 BOOL handled; |
114 OnChar(native_key_event.hwnd, native_key_event.message, | 110 OnChar(native_key_event.hwnd, native_key_event.message, |
115 native_key_event.wParam, native_key_event.lParam, &handled); | 111 native_key_event.wParam, native_key_event.lParam, &handled); |
116 return !!handled; // Don't send WM_CHAR for post event processing. | 112 if (handled) |
| 113 event->StopPropagation(); |
| 114 return; |
117 } | 115 } |
118 // Handles ctrl-shift key to change text direction and layout alignment. | 116 // Handles ctrl-shift key to change text direction and layout alignment. |
119 if (ui::IMM32Manager::IsRTLKeyboardLayoutInstalled() && | 117 if (ui::IMM32Manager::IsRTLKeyboardLayoutInstalled() && |
120 !IsTextInputTypeNone()) { | 118 !IsTextInputTypeNone()) { |
121 // TODO: shouldn't need to generate a KeyEvent here. | 119 // TODO: shouldn't need to generate a KeyEvent here. |
122 const ui::KeyEvent key(native_key_event); | 120 const ui::KeyEvent key(native_key_event); |
123 ui::KeyboardCode code = key.key_code(); | 121 ui::KeyboardCode code = key.key_code(); |
124 if (key.type() == ui::ET_KEY_PRESSED) { | 122 if (key.type() == ui::ET_KEY_PRESSED) { |
125 if (code == ui::VKEY_SHIFT) { | 123 if (code == ui::VKEY_SHIFT) { |
126 base::i18n::TextDirection dir; | 124 base::i18n::TextDirection dir; |
127 if (ui::IMM32Manager::IsCtrlShiftPressed(&dir)) | 125 if (ui::IMM32Manager::IsCtrlShiftPressed(&dir)) |
128 pending_requested_direction_ = dir; | 126 pending_requested_direction_ = dir; |
129 } else if (code != ui::VKEY_CONTROL) { | 127 } else if (code != ui::VKEY_CONTROL) { |
130 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; | 128 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; |
131 } | 129 } |
132 } else if (key.type() == ui::ET_KEY_RELEASED && | 130 } else if (key.type() == ui::ET_KEY_RELEASED && |
133 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) && | 131 (code == ui::VKEY_SHIFT || code == ui::VKEY_CONTROL) && |
134 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) { | 132 pending_requested_direction_ != base::i18n::UNKNOWN_DIRECTION) { |
135 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment( | 133 GetTextInputClient()->ChangeTextDirectionAndLayoutAlignment( |
136 pending_requested_direction_); | 134 pending_requested_direction_); |
137 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; | 135 pending_requested_direction_ = base::i18n::UNKNOWN_DIRECTION; |
138 } | 136 } |
139 } | 137 } |
140 | 138 |
141 bool destroyed = false; | 139 ui::EventDispatchDetails details = DispatchKeyEventPostIME(event); |
142 base::AutoReset<bool*> auto_reset(&destroyed_ptr_, &destroyed); | 140 if (!details.dispatcher_destroyed) |
143 bool handled = DispatchKeyEventPostIME(event); | 141 suppress_next_char_ = event->stopped_propagation(); |
144 if (destroyed) | |
145 return true; | |
146 suppress_next_char_ = handled; | |
147 return handled; | |
148 } | 142 } |
149 | 143 |
150 void InputMethodWin::OnTextInputTypeChanged(const TextInputClient* client) { | 144 void InputMethodWin::OnTextInputTypeChanged(const TextInputClient* client) { |
151 if (!IsTextInputClientFocused(client) || !IsWindowFocused(client)) | 145 if (!IsTextInputClientFocused(client) || !IsWindowFocused(client)) |
152 return; | 146 return; |
153 imm32_manager_.CancelIME(toplevel_window_handle_); | 147 imm32_manager_.CancelIME(toplevel_window_handle_); |
154 UpdateIMEState(); | 148 UpdateIMEState(); |
155 } | 149 } |
156 | 150 |
157 void InputMethodWin::OnCaretBoundsChanged(const TextInputClient* client) { | 151 void InputMethodWin::OnCaretBoundsChanged(const TextInputClient* client) { |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 return false; | 578 return false; |
585 // When Aura is enabled, |attached_window_handle| should always be a top-level | 579 // 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 | 580 // 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 | 581 // 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 | 582 // even when the |attached_window_handle| becomes active but has not received |
589 // WM_FOCUS yet. | 583 // WM_FOCUS yet. |
590 return toplevel_window_handle_ && | 584 return toplevel_window_handle_ && |
591 GetActiveWindow() == toplevel_window_handle_; | 585 GetActiveWindow() == toplevel_window_handle_; |
592 } | 586 } |
593 | 587 |
594 bool InputMethodWin::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) { | 588 void InputMethodWin::DispatchFabricatedKeyEvent(ui::KeyEvent* event) { |
595 if (event.is_char()) { | 589 if (event->is_char()) { |
596 if (suppress_next_char_) { | 590 if (suppress_next_char_) { |
597 suppress_next_char_ = false; | 591 suppress_next_char_ = false; |
598 return true; | 592 return; |
599 } | 593 } |
600 if (GetTextInputClient()) { | 594 if (GetTextInputClient()) { |
601 GetTextInputClient()->InsertChar( | 595 GetTextInputClient()->InsertChar( |
602 static_cast<base::char16>(event.key_code()), | 596 static_cast<base::char16>(event->key_code()), |
603 ui::GetModifiersFromKeyState()); | 597 ui::GetModifiersFromKeyState()); |
604 return true; | 598 return; |
605 } | 599 } |
606 } | 600 } |
607 return DispatchKeyEventPostIME(event); | 601 ignore_result(DispatchKeyEventPostIME(event)); |
608 } | 602 } |
609 | 603 |
610 void InputMethodWin::ConfirmCompositionText() { | 604 void InputMethodWin::ConfirmCompositionText() { |
611 if (composing_window_handle_) | 605 if (composing_window_handle_) |
612 imm32_manager_.CleanupComposition(composing_window_handle_); | 606 imm32_manager_.CleanupComposition(composing_window_handle_); |
613 | 607 |
614 if (!IsTextInputTypeNone()) { | 608 if (!IsTextInputTypeNone()) { |
615 // Though above line should confirm the client's composition text by sending | 609 // 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 | 610 // 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. | 611 // inconsistent states, we check the client's composition state again. |
(...skipping 19 matching lines...) Expand all Loading... |
637 enabled_ = true; | 631 enabled_ = true; |
638 break; | 632 break; |
639 } | 633 } |
640 | 634 |
641 imm32_manager_.SetTextInputMode(window_handle, text_input_mode); | 635 imm32_manager_.SetTextInputMode(window_handle, text_input_mode); |
642 tsf_inputscope::SetInputScopeForTsfUnawareWindow( | 636 tsf_inputscope::SetInputScopeForTsfUnawareWindow( |
643 window_handle, text_input_type, text_input_mode); | 637 window_handle, text_input_type, text_input_mode); |
644 } | 638 } |
645 | 639 |
646 } // namespace ui | 640 } // namespace ui |
OLD | NEW |