File: text_input_client.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (460 lines) | stat: -rw-r--r-- 20,676 bytes parent folder | download | duplicates (5)
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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_BASE_IME_TEXT_INPUT_CLIENT_H_
#define UI_BASE_IME_TEXT_INPUT_CLIENT_H_

#include <stddef.h>
#include <stdint.h>

#include <optional>
#include <ostream>
#include <string>
#include <string_view>
#include <vector>

#include "base/component_export.h"
#include "base/i18n/rtl.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "ui/base/ime/composition_text.h"
#include "ui/base/ime/grammar_fragment.h"
#include "ui/base/ime/ime_key_event_dispatcher.h"
#include "ui/base/ime/text_input_mode.h"
#include "ui/base/ime/text_input_type.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/range/range.h"
#include "url/gurl.h"

namespace gfx {
class Point;
class Rect;
}

namespace ui {

class KeyEvent;
enum class TextEditCommand;

#if BUILDFLAG(IS_WIN)
// Mirrors `dwFlags` for ITextStoreACP::GetACPFromPoint:
// https://learn.microsoft.com/en-us/windows/win32/api/textstor/nf-textstor-itextstoreacp-getacpfrompoint
enum class IndexFromPointFlags : uint8_t {
  kNone = 0,
  // Mirror of: GXFPF_ROUND_NEAREST
  // Overrides the default behavior of `GetACPFromPoint` if and only if a
  // character bounds contains `point`. Finds the index of the character which
  // has the closest origin to `point`.
  kNearestToContainedPoint = 0x01,
  // Mirror of: GXFPF_NEAREST
  // Overrides the default behavior of `GetACPFromPoint` if and only if no
  // character bounds contain `point`. Finds the index of the character which
  // has the closest origin to `point`.
  kNearestToUncontainedPoint = 0x02,
  // Alias for having both flags set. Always overrides the default behavior.
  // Finds the index of the character which has the closest origin to `point`.
  kNearestToPoint = kNearestToContainedPoint | kNearestToUncontainedPoint,
};
#endif  // BUILDFLAG(IS_WIN)

// An interface implemented by a View that needs text input support.
// All strings related to IME operations should be UTF-16 encoded and all
// indices/ranges relative to those strings should be UTF-16 code units.
class COMPONENT_EXPORT(UI_BASE_IME) TextInputClient {
 public:
  // The reason the control was focused, used by the virtual keyboard to detect
  // pen input.
  enum FocusReason {
    // Not focused.
    FOCUS_REASON_NONE,
    // User initiated with mouse.
    FOCUS_REASON_MOUSE,
    // User initiated with touch.
    FOCUS_REASON_TOUCH,
    // User initiated with pen.
    FOCUS_REASON_PEN,
    // All other reasons (e.g. system initiated, mouse)
    FOCUS_REASON_OTHER,
  };

#if BUILDFLAG(IS_CHROMEOS)
  enum SubClass {
    kRenderWidgetHostViewAura = 0,
    kArcImeService = 1,
    kTextField = 2,
    kMaxValue = kTextField,
  };
#endif

  virtual ~TextInputClient();

  // This should be implemented by the most concrete class.
  virtual base::WeakPtr<TextInputClient> AsWeakPtr() = 0;

  // Input method result -------------------------------------------------------

  // Sets composition text and attributes. If there is composition text already,
  // it'll be replaced by the new one. Otherwise, current selection will be
  // replaced. If there is no selection, the composition text will be inserted
  // at the insertion point.
  virtual void SetCompositionText(const ui::CompositionText& composition) = 0;

  // Converts current composition text into final content.
  // If keep_selection is true, keep the selected range unchanged
  // otherwise, set it to be after the newly committed text.
  // If text was committed, return the number of characters committed.
  // If we do not know what the number of characters committed is, return
  // std::numeric_limits<size_t>::max().
  virtual size_t ConfirmCompositionText(bool keep_selection) = 0;

  // Removes current composition text.
  virtual void ClearCompositionText() = 0;

  enum class InsertTextCursorBehavior {
    // Move cursor to the position after the last character in the text.
    // e.g. for "hello", the cursor will be right after "o".
    kMoveCursorAfterText,
    // Move cursor to the position before the first character in the text.
    // e.g. for "hello", the cursor will be right before "h".
    kMoveCursorBeforeText,
  };

  // Inserts a given text at the insertion point. Current composition text or
  // selection will be removed. This method should never be called when the
  // current text input type is TEXT_INPUT_TYPE_NONE.
  virtual void InsertText(const std::u16string& text,
                          InsertTextCursorBehavior cursor_behavior) = 0;

  // Inserts a single char at the insertion point. Unlike above InsertText()
  // method, this method takes an |event| parameter indicating
  // the event that was unprocessed. This method should only be
  // called when a key press is not handled by the input method but still
  // generates a character (eg. by the keyboard driver). In another word, the
  // preceding key press event should not be a VKEY_PROCESSKEY.
  // This method will be called whenever a char is generated by the keyboard,
  // even if the current text input type is TEXT_INPUT_TYPE_NONE.
  virtual void InsertChar(const ui::KeyEvent& event) = 0;

  // Returns whether the current insertion point supports images.
  virtual bool CanInsertImage();

  // Inserts a given image at the insertion point. It should be only called when
  // CanInsertImage returns true.
  virtual void InsertImage(const GURL& src) {}

  // Input context information -------------------------------------------------

  // Returns current text input type. It could be changed and even becomes
  // TEXT_INPUT_TYPE_NONE at runtime.
  virtual ui::TextInputType GetTextInputType() const = 0;

  // Returns current text input mode. It could be changed and even becomes
  // TEXT_INPUT_MODE_DEFAULT at runtime.
  virtual ui::TextInputMode GetTextInputMode() const = 0;

  // Returns the current text direction.
  virtual base::i18n::TextDirection GetTextDirection() const = 0;

  // Returns the current text input flags, which is a bit map of
  // WebTextInputType defined in blink. This is valid only for web input fileds;
  // it will return TEXT_INPUT_FLAG_NONE for native input fields.
  virtual int GetTextInputFlags() const = 0;

  // Returns if the client supports inline composition currently.
  virtual bool CanComposeInline() const = 0;

  // Returns current caret (insertion point) bounds in the universal screen
  // coordinates in DIP (Density Independent Pixel).
  // If there is selection, then the selection bounds will be returned.
  virtual gfx::Rect GetCaretBounds() const = 0;

  // Returns the bounds of the rectangle which encloses the selection region.
  // Bounds are in the screen coordinates. An empty value should be returned if
  // there is not any selection or this function is not implemented.
  virtual gfx::Rect GetSelectionBoundingBox() const = 0;

#if BUILDFLAG(IS_WIN)
  // For StylusHandwritingWin gesture support, this method mirrors the
  // expectations of ITextStoreACP::GetTextExt. Returns the smallest
  // axis-aligned bounding box which contains all of the axis-aligned character
  // bounding boxes specified by the character offset `range` [start, end).
  // The result is in DIP screen coordinates.
  //
  // For renderer content, "ProximateCharacterBounds" uses a cached subset of
  // the actual character bounding boxes, so requests for valid character
  // indices may fall outside of the cached rage. If `range` extends outside the
  // cached range, regardless of whether the character offset is valid for the
  // actual text, std::nullopt is returned.
  //
  // For views content, it's possible to retrieve accurate results for
  // "ProximateCharacterBounds" since the data is readily available. The caching
  // mechanism is to mitigate performance costs (CPU and memory) when processing
  // very large documents.
  virtual std::optional<gfx::Rect> GetProximateCharacterBounds(
      const gfx::Range& range) const = 0;

  // For StylusHandwritingWin gesture support, this method mirrors the
  // expectations of ITextStoreACP::GetACPFromPoint. Depending on which `flags`
  // are provided, returns an appropriate character offset relative to
  // `screen_point_in_dips`. See comments around IndexFromPointFlags and its
  // values for details.
  //
  // For renderer content, "ProximateCharacterBounds" uses a cached subset of
  // the actual character bounding boxes, so requests for `screen_point_in_dips`
  // contained by a character bounding box may not be considered "hit" by this
  // method if that character falls outside the cached range, or what's
  // considered "nearest" may be technically incorrect based on this fact. If
  // no `flags` are provided and `screen_point_in_dips` isn't contained by any
  // cached character bounds, regardless of whether `screen_point_in_dips` is
  // technically valid for the content, std::nullopt is returned. If either or
  // both `flags` are provided, this is guaranteed to return *some* character
  // offset, even if it's not the most appropriate offset based on the actual
  // content.
  //
  // For views content, it's possible to retrieve accurate results for
  // "ProximateCharacterBounds" since the data is readily available. The caching
  // mechanism is to mitigate performance costs (CPU and memory) when processing
  // very large documents.
  virtual std::optional<size_t> GetProximateCharacterIndexFromPoint(
      const gfx::Point& screen_point_in_dips,
      IndexFromPointFlags flags) const = 0;
#endif  // BUILDFLAG(IS_WIN)

  // Retrieves the composition character boundary rectangle in the universal
  // screen coordinates in DIP (Density Independent Pixel).
  // The |index| is zero-based index of character position in composition text.
  // Returns false if there is no composition text or |index| is out of range.
  // The |rect| is not touched in the case of failure.
  virtual bool GetCompositionCharacterBounds(size_t index,
                                             gfx::Rect* rect) const = 0;

  // Returns true if there is composition text.
  virtual bool HasCompositionText() const = 0;

  // Returns how the text input client was focused.
  virtual FocusReason GetFocusReason() const = 0;

  // Document content operations ----------------------------------------------

  // Retrieves the UTF-16 code unit range containing accessible text in
  // the View. It must cover the composition and selection range.
  // Returns false if the information cannot be retrieved right now.
  virtual bool GetTextRange(gfx::Range* range) const = 0;

  // Retrieves the UTF-16 code unit range of current composition text.
  // Returns false if the information cannot be retrieved right now.
  virtual bool GetCompositionTextRange(gfx::Range* range) const = 0;

  // Retrieves the UTF-16 code unit range of current selection in the text
  // input. Returns false if the information cannot be retrieved right now.
  // Returns false if the selected text is outside of the text input (== the
  // text input is not focused)
  virtual bool GetEditableSelectionRange(gfx::Range* range) const = 0;

  // Selects the given UTF-16 code unit range. Current composition text
  // will be confirmed before selecting the range.
  // Returns false if the operation is not supported.
  virtual bool SetEditableSelectionRange(const gfx::Range& range) = 0;

#if BUILDFLAG(IS_MAC)
  // Deletes contents in the given UTF-16 code unit range. Current
  // composition text will be confirmed before deleting the range.
  // The input caret will be moved to the place where the range gets deleted.
  // ExtendSelectionAndDelete should be used instead as far as you are deleting
  // characters around current caret. This function with the range based on
  // GetEditableSelectionRange has a race condition due to asynchronous IPCs
  // between browser and renderer. Returns false if the operation is not
  // supported.
  virtual bool DeleteRange(const gfx::Range& range) = 0;
#endif

  // Retrieves the text content in a given UTF-16 code unit range.
  // The result will be stored into |*text|.
  // Returns false if the operation is not supported or the specified range
  // is out of the text range returned by GetTextRange().
  virtual bool GetTextFromRange(const gfx::Range& range,
                                std::u16string* text) const = 0;

  // Miscellaneous ------------------------------------------------------------

  // Called whenever current keyboard layout or input method is changed,
  // especially the change of input locale and text direction.
  virtual void OnInputMethodChanged() = 0;

  // Called whenever the user requests to change the text direction and layout
  // alignment of the current text box. It's for supporting ctrl-shift on
  // Windows.
  // Returns false if the operation is not supported.
  virtual bool ChangeTextDirectionAndLayoutAlignment(
      base::i18n::TextDirection direction) = 0;

  // Deletes the current selection plus the specified number of char16 values
  // before and after the selection or caret. This function should be used
  // instead of calling DeleteRange with GetEditableSelectionRange, because
  // GetEditableSelectionRange may not be the latest value due to asynchronous
  // of IPC between browser and renderer.
  virtual void ExtendSelectionAndDelete(size_t before, size_t after) = 0;

#if BUILDFLAG(IS_CHROMEOS)
  // Deletes any active composition, and the current selection plus the
  // specified number of char16 values before and after the selection, and
  // replaces it with |replacement_string|.
  // Places the cursor at the end of |replacement_string|.
  //
  // Clients should try to implement this with an atomic operation to ensure
  // that input method features like autocorrection works well. However, it's
  // also okay for clients to fall back to ExtendSelectionAndDelete followed by
  // InsertText for a degraded experience.
  virtual void ExtendSelectionAndReplace(
      size_t length_before_selection,
      size_t length_after_selection,
      std::u16string_view replacement_string);
#endif

  // Ensure the caret is not in |rect|.  |rect| is in screen coordinates in
  // DIP (Density Independent Pixel) and may extend beyond the bounds of this
  // TextInputClient.
  virtual void EnsureCaretNotInRect(const gfx::Rect& rect) = 0;

  // Returns true if |command| is currently allowed to be executed.
  virtual bool IsTextEditCommandEnabled(TextEditCommand command) const = 0;

  // Execute |command| on the next key event. This allows a TextInputClient to
  // be informed of a platform-independent edit command that has been derived
  // from the key event currently being dispatched (but not yet sent to the
  // TextInputClient). The edit command will take into account any OS-specific,
  // or user-specified, keybindings that may be set up.
  virtual void SetTextEditCommandForNextKeyEvent(TextEditCommand command) = 0;

  // Returns a UKM source for identifying the input client (e.g. for web input
  // clients, the source represents the URL of the page).
  virtual ukm::SourceId GetClientSourceForMetrics() const = 0;

  // Returns whether text entered into this text client should be used to
  // improve typing suggestions for the user. This should return false for text
  // fields that are considered 'private' (e.g. in incognito tabs).
  virtual bool ShouldDoLearning() = 0;

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  // Start composition over a given UTF-16 code range from existing text. This
  // should only be used for composition scenario when IME wants to start
  // composition on existing text. Returns whether the operation was successful.
  // Must not be called with an invalid range.
  virtual bool SetCompositionFromExistingText(
      const gfx::Range& range,
      const std::vector<ui::ImeTextSpan>& ui_ime_text_spans) = 0;
#endif

#if BUILDFLAG(IS_CHROMEOS)
  // Return the start and end index of the autocorrect range. If non-existent,
  // return an empty Range.
  virtual gfx::Range GetAutocorrectRange() const = 0;

  // Return the location of the autocorrect range as a gfx::Rect object.
  // If gfx::Rect is empty, then the autocorrect character bounds have not been
  // set.
  // These bounds are in screen coordinates.
  virtual gfx::Rect GetAutocorrectCharacterBounds() const = 0;

  // Sets the autocorrect range to |range|. Clients should show some visual
  // indication of the range, such as flashing or underlining. If |range| is
  // empty, then the autocorrect range is cleared.
  // Returns true if the operation was successful. If |range| is invalid, then
  // no modifications are made and this function returns false.
  virtual bool SetAutocorrectRange(const gfx::Range& range) = 0;

  // Returns the grammar fragment which contains the current cursor. If
  // non-existent, returns nullopt.
  virtual std::optional<GrammarFragment> GetGrammarFragmentAtCursor() const;

  // Clears all the grammar fragments in |range|, returns whether the operation
  // is successful. Should return true if the there is no fragment in the range.
  virtual bool ClearGrammarFragments(const gfx::Range& range);

  // Adds new grammar markers according to |fragments|. Clients should show
  // some visual indications such as underlining. Returns whether the operation
  // is successful.
  virtual bool AddGrammarFragments(
      const std::vector<GrammarFragment>& fragments);

  // Does the current text client support always confirming a composition, even
  // if there isn't a composition currently set?
  virtual bool SupportsAlwaysConfirmComposition();
#endif

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
  // Returns false if either the focused editable element or the EditContext
  // bounds is not available, else it returns true with the control and
  // selection bounds for the EditContext or control bounds of the active
  // editable element. This is used to report the layout bounds of the text
  // input control to TSF on Windows and to the Virtual Keyboard extension on
  // ChromeOS.
  virtual void GetActiveTextInputControlLayoutBounds(
      std::optional<gfx::Rect>* control_bounds,
      std::optional<gfx::Rect>* selection_bounds) = 0;
#endif

#if BUILDFLAG(IS_WIN)
  // Notifies accessibility about active composition. This API is currently
  // only defined for TSF which is available only on Windows
  // https://docs.microsoft.com/en-us/windows/desktop/api/UIAutomationCore/
  // nf-uiautomationcore-itexteditprovider-getactivecomposition
  // It notifies the composition range, composition text and whether the
  // composition has been committed or not.
  virtual void SetActiveCompositionForAccessibility(
      const gfx::Range& range,
      const std::u16string& active_composition_text,
      bool is_composition_committed) = 0;
#endif

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
  struct EditingContext {
    // Contains the active web content's URL.
    GURL page_url;
  };

  virtual ui::TextInputClient::EditingContext GetTextEditingContext();

  // Notifies TSF when a frame with a committed Url receives focus.
  virtual void NotifyOnFrameFocusChanged() {}
#endif

  // Called before ui::InputMethod dispatches a not-consumed event to PostIME
  // phase. This method gives TextInputClient a chance to intercept event
  // dispatching.
  virtual void OnDispatchingKeyEventPostIME(ui::KeyEvent* event) {}
};

#if BUILDFLAG(IS_WIN)
COMPONENT_EXPORT(UI_BASE_IME)
extern std::ostream& operator<<(std::ostream& os, IndexFromPointFlags flags);
#endif  // BUILDFLAG(IS_WIN)

}  // namespace ui

#if BUILDFLAG(IS_WIN)
inline constexpr ui::IndexFromPointFlags operator&(ui::IndexFromPointFlags a,
                                                   ui::IndexFromPointFlags b) {
  using T = std::underlying_type_t<ui::IndexFromPointFlags>;
  return static_cast<ui::IndexFromPointFlags>(static_cast<T>(a) &
                                              static_cast<T>(b));
}

inline constexpr ui::IndexFromPointFlags operator|(ui::IndexFromPointFlags a,
                                                   ui::IndexFromPointFlags b) {
  using T = std::underlying_type_t<ui::IndexFromPointFlags>;
  return static_cast<ui::IndexFromPointFlags>(static_cast<T>(a) |
                                              static_cast<T>(b));
}

inline constexpr ui::IndexFromPointFlags& operator|=(
    ui::IndexFromPointFlags& a,
    ui::IndexFromPointFlags b) {
  a = a | b;
  return a;
}
#endif  // BUILDFLAG(IS_WIN)

#endif  // UI_BASE_IME_TEXT_INPUT_CLIENT_H_