text_input.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. // Copyright 2018 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. #ifndef COMPONENTS_EXO_TEXT_INPUT_H_
  5. #define COMPONENTS_EXO_TEXT_INPUT_H_
  6. #include <string>
  7. #include "base/i18n/rtl.h"
  8. #include "base/scoped_observation.h"
  9. #include "base/strings/string_piece.h"
  10. #include "components/exo/seat_observer.h"
  11. #include "third_party/abseil-cpp/absl/types/optional.h"
  12. #include "ui/base/ime/composition_text.h"
  13. #include "ui/base/ime/text_input_client.h"
  14. #include "ui/base/ime/text_input_flags.h"
  15. #include "ui/base/ime/text_input_mode.h"
  16. #include "ui/base/ime/text_input_type.h"
  17. #include "ui/base/ime/virtual_keyboard_controller.h"
  18. #include "ui/base/ime/virtual_keyboard_controller_observer.h"
  19. #include "ui/gfx/geometry/rect.h"
  20. #include "ui/gfx/range/range.h"
  21. namespace ui {
  22. class InputMethod;
  23. } // namespace ui
  24. namespace exo {
  25. class Surface;
  26. class Seat;
  27. // This class bridges the ChromeOS input method and a text-input context.
  28. // It can be inactive, active, or in a pending state where Activate() was
  29. // called but the associated window is not focused.
  30. class TextInput : public ui::TextInputClient,
  31. public ui::VirtualKeyboardControllerObserver,
  32. public SeatObserver {
  33. public:
  34. class Delegate {
  35. public:
  36. virtual ~Delegate() = default;
  37. // Called when the text input session is activated.
  38. virtual void Activated() = 0;
  39. // Called when the text input session is deactivated. TextInput does not
  40. // refer to the delegate anymore.
  41. virtual void Deactivated() = 0;
  42. // Called when the virtual keyboard visibility state has changed.
  43. virtual void OnVirtualKeyboardVisibilityChanged(bool is_visible) = 0;
  44. // Called when the virtual keyboard's occluded bounds has changed.
  45. // The bounds are in screen DIP.
  46. virtual void OnVirtualKeyboardOccludedBoundsChanged(
  47. const gfx::Rect& screen_bounds) = 0;
  48. // Set the 'composition text' of the current text input.
  49. virtual void SetCompositionText(const ui::CompositionText& composition) = 0;
  50. // Commit |text| to the current text input session.
  51. virtual void Commit(const std::u16string& text) = 0;
  52. // Set the cursor position.
  53. // |surrounding_text| is the current surrounding text.
  54. // The |selection| range is in UTF-16 offsets of the current surrounding
  55. // text. |selection| must be a valid range, i.e.
  56. // selection.IsValid() && selection.GetMax() <= surrounding_text.length().
  57. virtual void SetCursor(base::StringPiece16 surrounding_text,
  58. const gfx::Range& selection) = 0;
  59. // Delete the surrounding text of the current text input.
  60. // |surrounding_text| is the current surrounding text.
  61. // The delete |range| is in UTF-16 offsets of the current surrounding text.
  62. // |range| must be a valid range, i.e.
  63. // range.IsValid() && range.GetMax() <= surrounding_text.length().
  64. virtual void DeleteSurroundingText(base::StringPiece16 surrounding_text,
  65. const gfx::Range& range) = 0;
  66. // Sends a key event.
  67. virtual void SendKey(const ui::KeyEvent& event) = 0;
  68. // Called when the text direction has changed.
  69. virtual void OnTextDirectionChanged(
  70. base::i18n::TextDirection direction) = 0;
  71. // Sets composition from the current surrounding text offsets.
  72. // Offsets in |cursor| and |range| is relative to the beginning of
  73. // |surrounding_text|. Offsets in |ui_ime_text_spans| is relative to the new
  74. // composition, i.e. relative to |range|'s start. All offsets are in UTF16,
  75. // and must be valid.
  76. virtual void SetCompositionFromExistingText(
  77. base::StringPiece16 surrounding_text,
  78. const gfx::Range& cursor,
  79. const gfx::Range& range,
  80. const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) = 0;
  81. // Clears all the grammar fragments in |range|.
  82. // |surrounding_text| is the current surrounding text, used for utf16 to
  83. // utf8 conversion.
  84. virtual void ClearGrammarFragments(base::StringPiece16 surrounding_text,
  85. const gfx::Range& range) = 0;
  86. // Adds a new grammar marker according to |fragments|. Clients should show
  87. // some visual indications such as underlining.
  88. // |surrounding_text| is the current surrounding text, used for utf16 to
  89. // utf8 conversion.
  90. virtual void AddGrammarFragment(base::StringPiece16 surrounding_text,
  91. const ui::GrammarFragment& fragment) = 0;
  92. // Sets the autocorrect range from the current surrounding text offsets.
  93. // Offsets in |range| is relative to the beginning of
  94. // |surrounding_text|. All offsets are in UTF16, and must be valid.
  95. virtual void SetAutocorrectRange(base::StringPiece16 surrounding_text,
  96. const gfx::Range& range) = 0;
  97. };
  98. explicit TextInput(std::unique_ptr<Delegate> delegate);
  99. TextInput(const TextInput&) = delete;
  100. TextInput& operator=(const TextInput&) = delete;
  101. ~TextInput() override;
  102. // Request to activate the text input context on the surface. Activation will
  103. // occur immediately if the associated window is already focused, or
  104. // otherwise when the window gains focus.
  105. void Activate(Seat* seat, Surface* surface);
  106. // Deactivates the text input context.
  107. void Deactivate();
  108. // Shows the virtual keyboard if needed.
  109. void ShowVirtualKeyboardIfEnabled();
  110. // Hides the virtual keyboard.
  111. void HideVirtualKeyboard();
  112. // Re-synchronize the current status when the surrounding text has changed
  113. // during the text input session.
  114. void Resync();
  115. // Resets the current input method composition state.
  116. void Reset();
  117. // Sets the surrounding text in the app.
  118. // |cursor_pos| is the range of |text|.
  119. void SetSurroundingText(const std::u16string& text,
  120. const gfx::Range& cursor_pos);
  121. // Sets the text input type, mode, flags, and |should_do_learning|.
  122. void SetTypeModeFlags(ui::TextInputType type,
  123. ui::TextInputMode mode,
  124. int flags,
  125. bool should_do_learning);
  126. // Sets the bounds of the text caret, relative to the window origin.
  127. void SetCaretBounds(const gfx::Rect& bounds);
  128. // Sets grammar fragment at the cursor position.
  129. void SetGrammarFragmentAtCursor(
  130. const absl::optional<ui::GrammarFragment>& fragment);
  131. // Sets the autocorrect range and bounds. `autocorrect_bounds` is the
  132. // bounding rect around the autocorreced text, and are relative to
  133. // to the window origin.
  134. void SetAutocorrectInfo(const gfx::Range& autocorrect_range,
  135. const gfx::Rect& autocorrect_bounds);
  136. Delegate* delegate() { return delegate_.get(); }
  137. // ui::TextInputClient:
  138. void SetCompositionText(const ui::CompositionText& composition) override;
  139. size_t ConfirmCompositionText(bool keep_selection) override;
  140. void ClearCompositionText() override;
  141. void InsertText(const std::u16string& text,
  142. InsertTextCursorBehavior cursor_behavior) override;
  143. void InsertChar(const ui::KeyEvent& event) override;
  144. ui::TextInputType GetTextInputType() const override;
  145. ui::TextInputMode GetTextInputMode() const override;
  146. base::i18n::TextDirection GetTextDirection() const override;
  147. int GetTextInputFlags() const override;
  148. bool CanComposeInline() const override;
  149. gfx::Rect GetCaretBounds() const override;
  150. gfx::Rect GetSelectionBoundingBox() const override;
  151. bool GetCompositionCharacterBounds(size_t index,
  152. gfx::Rect* rect) const override;
  153. bool HasCompositionText() const override;
  154. ui::TextInputClient::FocusReason GetFocusReason() const override;
  155. bool GetTextRange(gfx::Range* range) const override;
  156. bool GetCompositionTextRange(gfx::Range* range) const override;
  157. bool GetEditableSelectionRange(gfx::Range* range) const override;
  158. bool SetEditableSelectionRange(const gfx::Range& range) override;
  159. bool GetTextFromRange(const gfx::Range& range,
  160. std::u16string* text) const override;
  161. void OnInputMethodChanged() override;
  162. bool ChangeTextDirectionAndLayoutAlignment(
  163. base::i18n::TextDirection direction) override;
  164. void ExtendSelectionAndDelete(size_t before, size_t after) override;
  165. void EnsureCaretNotInRect(const gfx::Rect& rect) override;
  166. bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override;
  167. void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override;
  168. ukm::SourceId GetClientSourceForMetrics() const override;
  169. bool ShouldDoLearning() override;
  170. bool SetCompositionFromExistingText(
  171. const gfx::Range& range,
  172. const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) override;
  173. gfx::Range GetAutocorrectRange() const override;
  174. gfx::Rect GetAutocorrectCharacterBounds() const override;
  175. bool SetAutocorrectRange(const gfx::Range& range) override;
  176. absl::optional<ui::GrammarFragment> GetGrammarFragmentAtCursor()
  177. const override;
  178. bool ClearGrammarFragments(const gfx::Range& range) override;
  179. bool AddGrammarFragments(
  180. const std::vector<ui::GrammarFragment>& fragments) override;
  181. void GetActiveTextInputControlLayoutBounds(
  182. absl::optional<gfx::Rect>* control_bounds,
  183. absl::optional<gfx::Rect>* selection_bounds) override {}
  184. // ui::VirtualKeyboardControllerObserver:
  185. void OnKeyboardVisible(const gfx::Rect& keyboard_rect) override;
  186. void OnKeyboardHidden() override;
  187. // SeatObserver:
  188. void OnSurfaceFocused(Surface* gained_focus,
  189. Surface* lost_focus,
  190. bool has_focused_surface) override;
  191. private:
  192. void AttachInputMethod();
  193. void DetachInputMethod();
  194. void ResetCompositionTextCache();
  195. // Delegate to talk to actual its client.
  196. std::unique_ptr<Delegate> delegate_;
  197. // On requesting to show Virtual Keyboard, InputMethod may not be connected.
  198. // So, remember the request temporarily, and then on InputMethod connection
  199. // show the Virtual Keyboard.
  200. bool pending_vk_visible_ = false;
  201. // |surface_| and |seat_| are non-null if and only if the TextInput is in a
  202. // pending or active state, in which case the TextInput will be observing the
  203. // Seat.
  204. Surface* surface_ = nullptr;
  205. Seat* seat_ = nullptr;
  206. // If the TextInput is active (associated window has focus) and the
  207. // InputMethod is available, this is set and the TextInput will be its
  208. // focused client. Otherwise, it is null and the TextInput is not attached
  209. // to any InputMethod, so the TextInputClient overrides will not be called.
  210. ui::InputMethod* input_method_ = nullptr;
  211. base::ScopedObservation<ui::VirtualKeyboardController,
  212. ui::VirtualKeyboardControllerObserver>
  213. virtual_keyboard_observation_{this};
  214. // Cache of the current caret bounding box, sent from the client.
  215. gfx::Rect caret_bounds_;
  216. // Cache of the current input field attributes sent from the client.
  217. ui::TextInputType input_type_ = ui::TEXT_INPUT_TYPE_NONE;
  218. ui::TextInputMode input_mode_ = ui::TEXT_INPUT_MODE_DEFAULT;
  219. int flags_ = ui::TEXT_INPUT_FLAG_NONE;
  220. bool should_do_learning_ = true;
  221. // Cache of the current surrounding text, sent from the client.
  222. std::u16string surrounding_text_;
  223. // Cache of the current cursor position in the surrounding text, sent from
  224. // the client. Maybe "invalid" value, if not available.
  225. gfx::Range cursor_pos_ = gfx::Range::InvalidRange();
  226. // Cache of the current composition range (set in absolute indices).
  227. gfx::Range composition_range_ = gfx::Range::InvalidRange();
  228. // Cache of the current composition, updated from Chrome OS IME.
  229. ui::CompositionText composition_;
  230. // Cache of the current text input direction, update from the Chrome OS IME.
  231. base::i18n::TextDirection direction_ = base::i18n::UNKNOWN_DIRECTION;
  232. // Cache of the grammar fragment at cursor position, send from Lacros side.
  233. // Wayland API sends the fragment range in utf8 and what IME needs is utf16.
  234. // To correctly convert the utf8 range to utf16, we need the updated
  235. // surrounding text, which is not available when we receive the grammar
  236. // fragment. It is guaranteed that on Lacros side, it always updates grammar
  237. // fragment before updating surrounding text. So we store the utf8 fragment in
  238. // |grammar_fragment_at_cursor_utf8_| when we receive it and when we receive
  239. // the surrounding text update next time, we convert the utf8 fragment to
  240. // utf16 fragment and store it in |grammar_fragment_at_cursor_utf16_|. When
  241. // IME requests current grammar fragment, we always return the utf16 version.
  242. absl::optional<ui::GrammarFragment> grammar_fragment_at_cursor_utf8_;
  243. absl::optional<ui::GrammarFragment> grammar_fragment_at_cursor_utf16_;
  244. struct AutocorrectInfo {
  245. gfx::Range range;
  246. gfx::Rect bounds;
  247. };
  248. // Latest autocorrect information that was sent from the Wayland client.
  249. // along with the last surrounding text change.
  250. AutocorrectInfo autocorrect_info_;
  251. // Latest autocorrect information that was received without a receiving a
  252. // corresponding surrounding text. Once this class receives a surrounding text
  253. // update, `autocorrect_info_` will take on this pending value, if it exists.
  254. absl::optional<AutocorrectInfo> pending_autocorrect_info_;
  255. };
  256. } // namespace exo
  257. #endif // COMPONENTS_EXO_TEXT_INPUT_H_