OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ui/views/mus/input_method_mus.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/memory/ptr_util.h" | |
10 #include "services/ui/public/cpp/window.h" | |
11 #include "services/ui/public/interfaces/constants.mojom.h" | |
12 #include "services/ui/public/interfaces/ime/ime.mojom.h" | |
13 #include "ui/base/ime/text_input_client.h" | |
14 #include "ui/events/event.h" | |
15 #include "ui/platform_window/mojo/ime_type_converters.h" | |
16 #include "ui/platform_window/mojo/text_input_state.mojom.h" | |
17 #include "ui/views/mus/text_input_client_impl.h" | |
18 | |
19 using ui::mojom::EventResult; | |
20 | |
21 namespace views { | |
22 | |
23 //////////////////////////////////////////////////////////////////////////////// | |
24 // InputMethodMus, public: | |
25 | |
26 InputMethodMus::InputMethodMus(ui::internal::InputMethodDelegate* delegate, | |
27 ui::Window* window) | |
28 : window_(window) { | |
29 SetDelegate(delegate); | |
30 } | |
31 | |
32 InputMethodMus::~InputMethodMus() {} | |
33 | |
34 void InputMethodMus::Init(service_manager::Connector* connector) { | |
35 connector->ConnectToInterface(ui::mojom::kServiceName, &ime_server_); | |
36 } | |
37 | |
38 void InputMethodMus::DispatchKeyEvent( | |
39 ui::KeyEvent* event, | |
40 std::unique_ptr<base::Callback<void(EventResult)>> ack_callback) { | |
41 DCHECK(event->type() == ui::ET_KEY_PRESSED || | |
42 event->type() == ui::ET_KEY_RELEASED); | |
43 | |
44 // If no text input client, do nothing. | |
45 if (!GetTextInputClient()) { | |
46 ignore_result(DispatchKeyEventPostIME(event)); | |
47 if (ack_callback) { | |
48 ack_callback->Run(event->handled() ? EventResult::HANDLED | |
49 : EventResult::UNHANDLED); | |
50 } | |
51 return; | |
52 } | |
53 | |
54 // IME driver will notify us whether it handled the event or not by calling | |
55 // ProcessKeyEventCallback(), in which we will run the |ack_callback| to tell | |
56 // the window server if client handled the event or not. | |
57 input_method_->ProcessKeyEvent( | |
58 ui::Event::Clone(*event), | |
59 base::Bind(&InputMethodMus::ProcessKeyEventCallback, | |
60 base::Unretained(this), *event, Passed(&ack_callback))); | |
61 } | |
62 | |
63 //////////////////////////////////////////////////////////////////////////////// | |
64 // InputMethodMus, ui::InputMethod implementation: | |
65 | |
66 void InputMethodMus::OnFocus() { | |
67 InputMethodBase::OnFocus(); | |
68 UpdateTextInputType(); | |
69 } | |
70 | |
71 void InputMethodMus::OnBlur() { | |
72 InputMethodBase::OnBlur(); | |
73 UpdateTextInputType(); | |
74 } | |
75 | |
76 bool InputMethodMus::OnUntranslatedIMEMessage(const base::NativeEvent& event, | |
77 NativeEventResult* result) { | |
78 // This method is not called on non-Windows platforms. See the comments for | |
79 // ui::InputMethod::OnUntranslatedIMEMessage(). | |
80 return false; | |
81 } | |
82 | |
83 void InputMethodMus::DispatchKeyEvent(ui::KeyEvent* event) { | |
84 DispatchKeyEvent(event, nullptr); | |
85 } | |
86 | |
87 void InputMethodMus::OnTextInputTypeChanged(const ui::TextInputClient* client) { | |
88 if (IsTextInputClientFocused(client)) | |
89 UpdateTextInputType(); | |
90 InputMethodBase::OnTextInputTypeChanged(client); | |
91 | |
92 if (input_method_) { | |
93 input_method_->OnTextInputTypeChanged( | |
94 static_cast<ui::mojom::TextInputType>(client->GetTextInputType())); | |
95 } | |
96 } | |
97 | |
98 void InputMethodMus::OnCaretBoundsChanged(const ui::TextInputClient* client) { | |
99 if (input_method_) | |
100 input_method_->OnCaretBoundsChanged(client->GetCaretBounds()); | |
101 } | |
102 | |
103 void InputMethodMus::CancelComposition(const ui::TextInputClient* client) { | |
104 if (input_method_) | |
105 input_method_->CancelComposition(); | |
106 } | |
107 | |
108 void InputMethodMus::OnInputLocaleChanged() { | |
109 // TODO(moshayedi): crbug.com/637418. Not supported in ChromeOS. Investigate | |
110 // whether we want to support this or not. | |
111 } | |
112 | |
113 bool InputMethodMus::IsCandidatePopupOpen() const { | |
114 // TODO(moshayedi): crbug.com/637416. Implement this properly when we have a | |
115 // mean for displaying candidate list popup. | |
116 return false; | |
117 } | |
118 | |
119 void InputMethodMus::OnDidChangeFocusedClient( | |
120 ui::TextInputClient* focused_before, | |
121 ui::TextInputClient* focused) { | |
122 InputMethodBase::OnDidChangeFocusedClient(focused_before, focused); | |
123 UpdateTextInputType(); | |
124 | |
125 text_input_client_ = base::MakeUnique<TextInputClientImpl>(focused); | |
126 ime_server_->StartSession(text_input_client_->CreateInterfacePtrAndBind(), | |
127 MakeRequest(&input_method_)); | |
128 } | |
129 | |
130 void InputMethodMus::UpdateTextInputType() { | |
131 ui::TextInputType type = GetTextInputType(); | |
132 mojo::TextInputStatePtr state = mojo::TextInputState::New(); | |
133 state->type = mojo::ConvertTo<mojo::TextInputType>(type); | |
134 if (window_) { | |
135 if (type != ui::TEXT_INPUT_TYPE_NONE) | |
136 window_->SetImeVisibility(true, std::move(state)); | |
137 else | |
138 window_->SetTextInputState(std::move(state)); | |
139 } | |
140 } | |
141 | |
142 void InputMethodMus::ProcessKeyEventCallback( | |
143 const ui::KeyEvent& event, | |
144 std::unique_ptr<base::Callback<void(EventResult)>> ack_callback, | |
145 bool handled) { | |
146 EventResult event_result; | |
147 if (!handled) { | |
148 // If not handled by IME, try dispatching the event to delegate to see if | |
149 // any client-side post-ime processing needs to be done. This includes cases | |
150 // like backspace, return key, etc. | |
151 std::unique_ptr<ui::Event> event_clone = ui::Event::Clone(event); | |
152 ignore_result(DispatchKeyEventPostIME(event_clone->AsKeyEvent())); | |
153 event_result = | |
154 event_clone->handled() ? EventResult::HANDLED : EventResult::UNHANDLED; | |
155 } else { | |
156 event_result = EventResult::HANDLED; | |
157 } | |
158 // |ack_callback| can be null if the standard form of DispatchKeyEvent() is | |
159 // called instead of the version which provides a callback. In mus+ash we | |
160 // use the version with callback, but some unittests use the standard form. | |
161 if (ack_callback) | |
162 ack_callback->Run(event_result); | |
163 } | |
164 | |
165 } // namespace views | |
OLD | NEW |