OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_tsf.h" | 5 #include "ui/base/ime/input_method_tsf.h" |
6 | 6 |
7 #include "ui/base/ime/text_input_client.h" | 7 #include "ui/base/ime/text_input_client.h" |
8 #include "ui/base/ime/win/tsf_bridge.h" | 8 #include "ui/base/ime/win/tsf_bridge.h" |
| 9 #include "ui/base/ime/win/tsf_event_router.h" |
9 | 10 |
10 namespace ui { | 11 namespace ui { |
11 | 12 |
| 13 class InputMethodTSF::TSFEventObserver : public TSFEventRouterObserver { |
| 14 public: |
| 15 TSFEventObserver() : is_candidate_popup_open_(false) {} |
| 16 |
| 17 // Returns true if we know for sure that a candidate window (or IME suggest, |
| 18 // etc.) is open. |
| 19 bool IsCandidatePopupOpen() const { return is_candidate_popup_open_; } |
| 20 |
| 21 // Overridden from TSFEventRouterObserver: |
| 22 virtual void OnCandidateWindowCountChanged(size_t window_count) OVERRIDE { |
| 23 is_candidate_popup_open_ = (window_count != 0); |
| 24 } |
| 25 |
| 26 private: |
| 27 // True if we know for sure that a candidate window is open. |
| 28 bool is_candidate_popup_open_; |
| 29 |
| 30 DISALLOW_COPY_AND_ASSIGN(TSFEventObserver); |
| 31 }; |
| 32 |
12 InputMethodTSF::InputMethodTSF(internal::InputMethodDelegate* delegate, | 33 InputMethodTSF::InputMethodTSF(internal::InputMethodDelegate* delegate, |
13 HWND toplevel_window_handle) | 34 HWND toplevel_window_handle) |
14 : InputMethodWin(delegate, toplevel_window_handle) { | 35 : InputMethodWin(delegate, toplevel_window_handle), |
| 36 tsf_event_observer_(new TSFEventObserver()), |
| 37 tsf_event_router_(new TSFEventRouter(tsf_event_observer_.get())) { |
15 // In non-Aura environment, appropriate callbacks to OnFocus() and OnBlur() | 38 // In non-Aura environment, appropriate callbacks to OnFocus() and OnBlur() |
16 // are not implemented yet. To work around this limitation, here we use | 39 // are not implemented yet. To work around this limitation, here we use |
17 // "always focused" model. | 40 // "always focused" model. |
18 // TODO(ime): Fix the caller of OnFocus() and OnBlur() so that appropriate | 41 // TODO(ime): Fix the caller of OnFocus() and OnBlur() so that appropriate |
19 // focus event will be passed. | 42 // focus event will be passed. |
20 InputMethodWin::OnFocus(); | 43 InputMethodWin::OnFocus(); |
21 } | 44 } |
22 | 45 |
| 46 InputMethodTSF::~InputMethodTSF() {} |
| 47 |
23 void InputMethodTSF::OnFocus() { | 48 void InputMethodTSF::OnFocus() { |
24 // Ignore OnFocus event for "always focused" model. See the comment in the | 49 // Do not call baseclass' OnFocus() and discard the event being in |
25 // constructor. | 50 // "always focused" model. See the comment in the constructor. |
26 // TODO(ime): Implement OnFocus once the callers are fixed. | 51 // TODO(ime): Implement OnFocus once the callers are fixed. |
| 52 |
| 53 tsf_event_router_->SetManager( |
| 54 ui::TSFBridge::GetInstance()->GetThreadManager()); |
27 } | 55 } |
28 | 56 |
29 void InputMethodTSF::OnBlur() { | 57 void InputMethodTSF::OnBlur() { |
30 // Ignore OnBlur event for "always focused" model. See the comment in the | 58 // Do not call baseclass' OnBlur() and discard the event being in |
31 // constructor. | 59 // "always focused" model. See the comment in the constructor. |
32 // TODO(ime): Implement OnFocus once the callers are fixed. | 60 // TODO(ime): Implement OnFocus once the callers are fixed. |
| 61 |
| 62 tsf_event_router_->SetManager(NULL); |
33 } | 63 } |
34 | 64 |
35 bool InputMethodTSF::OnUntranslatedIMEMessage( | 65 bool InputMethodTSF::OnUntranslatedIMEMessage( |
36 const base::NativeEvent& event, InputMethod::NativeEventResult* result) { | 66 const base::NativeEvent& event, InputMethod::NativeEventResult* result) { |
37 LRESULT original_result = 0; | 67 LRESULT original_result = 0; |
38 BOOL handled = FALSE; | 68 BOOL handled = FALSE; |
39 // Even when TSF is enabled, following IMM32/Win32 messages must be handled. | 69 // Even when TSF is enabled, following IMM32/Win32 messages must be handled. |
40 switch (event.message) { | 70 switch (event.message) { |
41 case WM_IME_REQUEST: | 71 case WM_IME_REQUEST: |
42 // Some TSF-native TIPs (Text Input Processors) such as ATOK and Mozc | 72 // Some TSF-native TIPs (Text Input Processors) such as ATOK and Mozc |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 } else if (!client) { | 122 } else if (!client) { |
93 // SetFocusedTextInputClient(NULL) must be interpreted as | 123 // SetFocusedTextInputClient(NULL) must be interpreted as |
94 // "Remove the attached client". | 124 // "Remove the attached client". |
95 ui::TSFBridge::GetInstance()->RemoveFocusedClient( | 125 ui::TSFBridge::GetInstance()->RemoveFocusedClient( |
96 ui::TSFBridge::GetInstance()->GetFocusedTextInputClient()); | 126 ui::TSFBridge::GetInstance()->GetFocusedTextInputClient()); |
97 } | 127 } |
98 InputMethodWin::SetFocusedTextInputClient(client); | 128 InputMethodWin::SetFocusedTextInputClient(client); |
99 } | 129 } |
100 | 130 |
101 bool InputMethodTSF::IsCandidatePopupOpen() const { | 131 bool InputMethodTSF::IsCandidatePopupOpen() const { |
102 // TODO(yukishiino): Implement this method. | 132 return tsf_event_observer_->IsCandidatePopupOpen(); |
103 return false; | |
104 } | 133 } |
105 | 134 |
106 void InputMethodTSF::OnWillChangeFocusedClient(TextInputClient* focused_before, | 135 void InputMethodTSF::OnWillChangeFocusedClient(TextInputClient* focused_before, |
107 TextInputClient* focused) { | 136 TextInputClient* focused) { |
108 if (IsWindowFocused(focused_before)) { | 137 if (IsWindowFocused(focused_before)) { |
109 ConfirmCompositionText(); | 138 ConfirmCompositionText(); |
110 ui::TSFBridge::GetInstance()->RemoveFocusedClient(focused_before); | 139 ui::TSFBridge::GetInstance()->RemoveFocusedClient(focused_before); |
111 } | 140 } |
112 } | 141 } |
113 | 142 |
(...skipping 19 matching lines...) Expand all Loading... |
133 } | 162 } |
134 | 163 |
135 bool InputMethodTSF::IsWindowFocused(const TextInputClient* client) const { | 164 bool InputMethodTSF::IsWindowFocused(const TextInputClient* client) const { |
136 if (!client) | 165 if (!client) |
137 return false; | 166 return false; |
138 HWND attached_window_handle = GetAttachedWindowHandle(client); | 167 HWND attached_window_handle = GetAttachedWindowHandle(client); |
139 return attached_window_handle && GetFocus() == attached_window_handle; | 168 return attached_window_handle && GetFocus() == attached_window_handle; |
140 } | 169 } |
141 | 170 |
142 } // namespace ui | 171 } // namespace ui |
OLD | NEW |