File: text_input_client_mac.h

package info (click to toggle)
chromium 143.0.7499.109-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,786,824 kB
  • sloc: cpp: 35,783,839; ansic: 7,477,365; javascript: 3,962,116; python: 1,480,521; xml: 764,832; asm: 710,816; pascal: 188,028; sh: 88,717; perl: 88,692; objc: 79,984; sql: 57,625; cs: 42,265; fortran: 24,101; makefile: 22,509; tcl: 15,277; php: 14,018; yacc: 9,043; ruby: 7,553; awk: 3,720; lisp: 3,233; lex: 1,330; ada: 727; jsp: 228; sed: 36
file content (137 lines) | stat: -rw-r--r-- 5,766 bytes parent folder | download | duplicates (2)
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
// 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 CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_CLIENT_MAC_H_
#define CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_CLIENT_MAC_H_

#include <limits>

#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/no_destructor.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "ui/base/mojom/attributed_string.mojom-forward.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"

namespace gfx {
class Range;
}

namespace content {
class RenderWidgetHost;

// This class does synchronous IPC calls to the renderer process in order to
// help implement the synchronous NSTextInputClient API.
//
// The implementation involves two one-way IPC calls: a call is made to the
// renderer process and the renderer replies with a separate IPC call. If the
// reply is not received before a timeout fires, then the sync IPC is considered
// to have failed.
//
// This is done because Mojo sync calls do not have timeouts, and therefore they
// are unsuitable for use with an untrusted process.
//
// This class also handles async calls for the dictionary popup
// (`GetStringAtPoint` and `GetStringFromRange`). While these implementation
// details of dictionary lookup were originally added here as sync calls
// (they're now async), they remain here as they are also used in testing and
// thus it is convenient to have them on this class.
class CONTENT_EXPORT TextInputClientMac {
 public:
  static TextInputClientMac* GetInstance();

  TextInputClientMac(const TextInputClientMac&) = delete;
  TextInputClientMac& operator=(const TextInputClientMac&) = delete;

  // ---- Sync IME implementation methods ----

  // These two methods have an associated pair of methods to get data from the
  // renderer. The Get*() methods block the calling thread (always the UI
  // thread) with a short timeout after the async message has been sent to the
  // renderer to lookup the information needed to respond to the system. The
  // Set*AndSignal() methods store the looked up information in this service and
  // signal the condition to allow the Get*() methods to unlock and return that
  // stored value.

  // Gets the index of the character at the specified point (in Blink
  // coordinates, in physical pixels). Returns UINT32_MAX if the request times
  // out or is not completed.
  uint32_t GetCharacterIndexAtPoint(RenderWidgetHost* rwh,
                                    const gfx::Point& point);
  // Gets the first rect of characters in the specified range. Returns
  // NSZeroRect if the request times out or is not completed. The result is in
  // Blink coordinates, in physical pixels.
  gfx::Rect GetFirstRectForRange(RenderWidgetHost* rwh,
                                 const gfx::Range& range);

  // When the renderer sends a reply, it will be received by TextInputHostImpl
  // (which implements the mojo interface), which will call the corresponding
  // method on the IO thread to unlock the condition and allow the Get*()
  // methods to continue/return.
  void SetCharacterIndexAndSignal(uint32_t index);
  void SetFirstRectAndSignal(const gfx::Rect& first_rect);

  // ---- Dictionary lookup implementation methods ----

  // A shared callback for the following two methods. The values returned are:
  //   - The attributed string, either of the word that contains the given point
  //     (for GetStringAtPoint) or of the string specified by the given range
  //     (for GetStringFromRange) and
  //   - The lower-left baseline coordinate (in Blink coordinates, in physical
  //     pixels) of the returned string as displayed on the screen.
  using GetStringCallback =
      base::OnceCallback<void(ui::mojom::AttributedStringPtr,
                              const gfx::Point&)>;

  // Given a point (in Blink coordinates, in physical pixels), looks up a word
  // in the given RenderWidgetHost.
  //
  // This method is useful for implementing -quickLookWithEvent:, which AppKit
  // calls when the user taps on a view using 3 fingers.
  void GetStringAtPoint(RenderWidgetHost* rwh,
                        const gfx::Point& point,
                        GetStringCallback callback);

  // Given a range, looks up a string in the given RenderWidgetHost.
  //
  // This method is useful for implementing "Look Up <<selection>>" in the
  // context menu.
  void GetStringFromRange(RenderWidgetHost* rwh,
                          const gfx::Range& range,
                          GetStringCallback callback);

 private:
  friend base::NoDestructor<TextInputClientMac>;
  FRIEND_TEST_ALL_PREFIXES(TextInputClientMacTest, TimeoutRectForRange);
  TextInputClientMac();
  ~TextInputClientMac();

  // The critical sections that the Condition guards are in Get*() methods.
  // These methods lock the internal condition for use before the asynchronous
  // message is sent to the renderer to lookup the required information. These
  // are only used on the UI thread.
  void BeforeRequest() EXCLUSIVE_LOCK_FUNCTION(lock_);

  // Called at the end of a critical section. This will release the lock and
  // condition.
  void AfterRequest() UNLOCK_FUNCTION(lock_);

  uint32_t character_index_ = std::numeric_limits<uint32_t>::max();
  gfx::Rect first_rect_;

  base::Lock lock_;
  base::ConditionVariable condition_;

  // The amount of time that the browser process will wait for a response from
  // the renderer.
  base::TimeDelta wait_timeout_;
};

}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_CLIENT_MAC_H_