| 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 |