1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_TEXT_INPUT_H_
#define COMPONENTS_EXO_TEXT_INPUT_H_
#include <string>
#include "base/i18n/rtl.h"
#include "base/strings/string_piece.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/ime/composition_text.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/ime/text_input_flags.h"
#include "ui/base/ime/text_input_mode.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/base/ime/virtual_keyboard_controller_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/range/range.h"
namespace ui {
class InputMethod;
}
namespace exo {
class Surface;
// This class bridges the ChromeOS input method and a text-input context.
class TextInput : public ui::TextInputClient,
public ui::VirtualKeyboardControllerObserver {
public:
class Delegate {
public:
virtual ~Delegate() = default;
// Called when the text input session is activated.
virtual void Activated() = 0;
// Called when the text input session is deactivated. TextInput does not
// refer to the delegate anymore.
virtual void Deactivated() = 0;
// Called when the virtual keyboard visibility state has changed.
virtual void OnVirtualKeyboardVisibilityChanged(bool is_visible) = 0;
// Set the 'composition text' of the current text input.
virtual void SetCompositionText(const ui::CompositionText& composition) = 0;
// Commit |text| to the current text input session.
virtual void Commit(const std::u16string& text) = 0;
// Set the cursor position.
// |surrounding_text| is the current surrounding text.
// The |selection| range is in UTF-16 offsets of the current surrounding
// text. |selection| must be a valid range, i.e.
// selection.IsValid() && selection.GetMax() <= surrounding_text.length().
virtual void SetCursor(base::StringPiece16 surrounding_text,
const gfx::Range& selection) = 0;
// Delete the surrounding text of the current text input.
// |surrounding_text| is the current surrounding text.
// The delete |range| is in UTF-16 offsets of the current surrounding text.
// |range| must be a valid range, i.e.
// range.IsValid() && range.GetMax() <= surrounding_text.length().
virtual void DeleteSurroundingText(base::StringPiece16 surrounding_text,
const gfx::Range& range) = 0;
// Sends a key event.
virtual void SendKey(const ui::KeyEvent& event) = 0;
// Called when the text direction has changed.
virtual void OnTextDirectionChanged(
base::i18n::TextDirection direction) = 0;
// Sets composition from the current surrounding text offsets.
// Offsets in |cursor| and |range| is relative to the beginning of
// |surrounding_text|. Offsets in |ui_ime_text_spans| is relative to the new
// composition, i.e. relative to |range|'s start. All offsets are in UTF16,
// and must be valid.
virtual void SetCompositionFromExistingText(
base::StringPiece16 surrounding_text,
const gfx::Range& cursor,
const gfx::Range& range,
const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) = 0;
};
explicit TextInput(std::unique_ptr<Delegate> delegate);
TextInput(const TextInput&) = delete;
TextInput& operator=(const TextInput&) = delete;
~TextInput() override;
// Activates the text input context on the surface. Note that surface can be
// an app surface (hosted by a shell surface) or can be an independent one
// created by the text-input client.
void Activate(Surface* surface);
// Deactivates the text input context.
void Deactivate();
// Shows the virtual keyboard if needed.
void ShowVirtualKeyboardIfEnabled();
// Hides the virtual keyboard.
void HideVirtualKeyboard();
// Re-synchronize the current status when the surrounding text has changed
// during the text input session.
void Resync();
// Resets the current input method state.
void Reset();
// Sets the surrounding text in the app.
// |cursor_pos| is the range of |text|.
void SetSurroundingText(const std::u16string& text,
const gfx::Range& cursor_pos);
// Sets the text input type, mode, flags, and |should_do_learning|.
void SetTypeModeFlags(ui::TextInputType type,
ui::TextInputMode mode,
int flags,
bool should_do_learning);
// Sets the bounds of the text caret, relative to the window origin.
void SetCaretBounds(const gfx::Rect& bounds);
Delegate* delegate() { return delegate_.get(); }
// ui::TextInputClient:
void SetCompositionText(const ui::CompositionText& composition) override;
uint32_t ConfirmCompositionText(bool keep_selection) override;
void ClearCompositionText() override;
void InsertText(const std::u16string& text,
InsertTextCursorBehavior cursor_behavior) override;
void InsertChar(const ui::KeyEvent& event) override;
ui::TextInputType GetTextInputType() const override;
ui::TextInputMode GetTextInputMode() const override;
base::i18n::TextDirection GetTextDirection() const override;
int GetTextInputFlags() const override;
bool CanComposeInline() const override;
gfx::Rect GetCaretBounds() const override;
gfx::Rect GetSelectionBoundingBox() const override;
bool GetCompositionCharacterBounds(uint32_t index,
gfx::Rect* rect) const override;
bool HasCompositionText() const override;
ui::TextInputClient::FocusReason GetFocusReason() const override;
bool GetTextRange(gfx::Range* range) const override;
bool GetCompositionTextRange(gfx::Range* range) const override;
bool GetEditableSelectionRange(gfx::Range* range) const override;
bool SetEditableSelectionRange(const gfx::Range& range) override;
bool DeleteRange(const gfx::Range& range) override;
bool GetTextFromRange(const gfx::Range& range,
std::u16string* text) const override;
void OnInputMethodChanged() override;
bool ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection direction) override;
void ExtendSelectionAndDelete(size_t before, size_t after) override;
void EnsureCaretNotInRect(const gfx::Rect& rect) override;
bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override;
void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override;
ukm::SourceId GetClientSourceForMetrics() const override;
bool ShouldDoLearning() override;
bool SetCompositionFromExistingText(
const gfx::Range& range,
const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) override;
gfx::Range GetAutocorrectRange() const override;
gfx::Rect GetAutocorrectCharacterBounds() const override;
bool SetAutocorrectRange(const gfx::Range& range) override;
absl::optional<ui::GrammarFragment> GetGrammarFragment(
const gfx::Range& range) override;
bool ClearGrammarFragments(const gfx::Range& range) override;
bool AddGrammarFragments(
const std::vector<ui::GrammarFragment>& fragments) override;
void GetActiveTextInputControlLayoutBounds(
absl::optional<gfx::Rect>* control_bounds,
absl::optional<gfx::Rect>* selection_bounds) override {}
// ui::VirtualKeyboardControllerObserver:
void OnKeyboardVisible(const gfx::Rect& keyboard_rect) override;
void OnKeyboardHidden() override;
private:
void AttachInputMethod(aura::Window* window);
void DetachInputMethod();
void ResetCompositionTextCache();
// Delegate to talk to actual its client.
std::unique_ptr<Delegate> delegate_;
// On requesting to show Virtual Keyboard, InputMethod may not be connected.
// So, remember the request temporarily, and then on InputMethod connection
// show the Virtual Keyboard.
bool pending_vk_visible_ = false;
// Window instance that this TextInput is activated against.
aura::Window* window_ = nullptr;
// InputMethod in Chrome OS that this TextInput is attached to.
ui::InputMethod* input_method_ = nullptr;
// Cache of the current caret bounding box, sent from the client.
gfx::Rect caret_bounds_;
// Cache of the current input field attributes sent from the client.
ui::TextInputType input_type_ = ui::TEXT_INPUT_TYPE_NONE;
ui::TextInputMode input_mode_ = ui::TEXT_INPUT_MODE_DEFAULT;
int flags_ = ui::TEXT_INPUT_FLAG_NONE;
bool should_do_learning_ = true;
// Cache of the current surrounding text, sent from the client.
std::u16string surrounding_text_;
// Cache of the current cursor position in the surrounding text, sent from
// the client. Maybe "invalid" value, if not available.
gfx::Range cursor_pos_ = gfx::Range::InvalidRange();
// Cache of the current composition range (set in absolute indices).
gfx::Range composition_range_ = gfx::Range::InvalidRange();
// Cache of the current composition, updated from Chrome OS IME.
ui::CompositionText composition_;
// Cache of the current text input direction, update from the Chrome OS IME.
base::i18n::TextDirection direction_ = base::i18n::UNKNOWN_DIRECTION;
};
} // namespace exo
#endif // COMPONENTS_EXO_TEXT_INPUT_H_
|