File: wayland_input_method_context.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 (192 lines) | stat: -rw-r--r-- 7,972 bytes parent folder | download | duplicates (4)
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
// Copyright 2018 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_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_INPUT_METHOD_CONTEXT_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_INPUT_METHOD_CONTEXT_H_

#include <memory>
#include <string_view>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/nix/xdg_util.h"
#include "ui/base/ime/character_composer.h"
#include "ui/base/ime/linux/linux_input_method_context.h"
#include "ui/base/ime/surrounding_text_tracker.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/ime/virtual_keyboard_controller.h"
#include "ui/gfx/range/range.h"
#include "ui/ozone/platform/wayland/host/wayland_keyboard.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/ozone/platform/wayland/host/zwp_text_input_v1.h"
#include "ui/ozone/platform/wayland/host/zwp_text_input_v3.h"

namespace ui {

class WaylandConnection;

class WaylandInputMethodContext : public LinuxInputMethodContext,
                                  public VirtualKeyboardController,
                                  public WaylandWindow::FocusClient {
 public:
  class Delegate;

  WaylandInputMethodContext(WaylandConnection* connection,
                            WaylandKeyboard::Delegate* key_delegate,
                            LinuxInputMethodContextDelegate* ime_delegate);
  WaylandInputMethodContext(const WaylandInputMethodContext&) = delete;
  WaylandInputMethodContext& operator=(const WaylandInputMethodContext&) =
      delete;
  ~WaylandInputMethodContext() override;

  void Init();

  // LinuxInputMethodContext overrides:
  bool DispatchKeyEvent(const KeyEvent& key_event) override;
  // Returns true if this event comes from extended_keyboard::peek_key.
  // See also WaylandEventSource::OnKeyboardKeyEvent about how the flag is set.
  bool IsPeekKeyEvent(const KeyEvent& key_event) override;
  void SetCursorLocation(const gfx::Rect& rect) override;
  void SetSurroundingText(const std::u16string& text,
                          const gfx::Range& text_range,
                          const gfx::Range& composition_range,
                          const gfx::Range& selection_range) override;
  void WillUpdateFocus(TextInputClient* old_client,
                       TextInputClient* new_client) override;
  void UpdateFocus(bool has_client,
                   TextInputType old_type,
                   const TextInputClientAttributes& new_client_attributes,
                   TextInputClient::FocusReason reason) override;
  void Reset() override;
  VirtualKeyboardController* GetVirtualKeyboardController() override;

  // VirtualKeyboardController overrides:
  bool DisplayVirtualKeyboard() override;
  void DismissVirtualKeyboard() override;
  void AddObserver(VirtualKeyboardControllerObserver* observer) override;
  void RemoveObserver(VirtualKeyboardControllerObserver* observer) override;
  bool IsKeyboardVisible() override;

  // WaylandWindow::FocusClient overrides:
  void OnKeyboardFocusChanged(bool focused) override;
  void OnTextInputFocusChanged(bool focused) override;

  // Callbacks from the v1 and v3 clients.
  void OnPreeditString(std::string_view text,
                       const std::vector<SpanStyle>& spans,
                       const gfx::Range& preedit_cursor);
  void OnCommitString(std::string_view text);
  void OnCursorPosition(int32_t index, int32_t anchor);
  void OnDeleteSurroundingText(int32_t index, uint32_t length);
  void OnKeysym(uint32_t keysym,
                uint32_t state,
                uint32_t modifiers,
                uint32_t time);

  void OnInputPanelState(uint32_t state);
  void OnModifiersMap(std::vector<std::string> modifiers_map);

  const SurroundingTextTracker::State& predicted_state_for_testing() const {
    return surrounding_text_tracker_.predicted_state();
  }

  void SetTextInputV1ForTesting(ZwpTextInputV1* text_input_v1);

  void SetTextInputV3ForTesting(ZwpTextInputV3* text_input_v3);

  void SetDesktopEnvironmentForTesting(
      base::nix::DesktopEnvironment desktop_environment) {
    desktop_environment_ = desktop_environment;
  }

 private:
  void CreateTextInput();
  void Focus(bool skip_virtual_keyboard_update);
  void Blur(bool skip_virtual_keyboard_update);
  void UpdatePreeditText(const std::u16string& preedit_text);
  bool WindowIsActiveForTextInputV1() const;
  // If |skip_virtual_keyboard_update| is true, no virtual keyboard show/hide
  // requests will be sent. This is used to prevent flickering the virtual
  // keyboard when it would be immediately reshown anyway, e.g. when changing
  // focus from one text input to another.
  void MaybeUpdateActivated(bool skip_virtual_keyboard_update);

  const raw_ptr<WaylandConnection>
      connection_;  // TODO(jani) Handle this better

  // Delegate key events to be injected into PlatformEvent system.
  const raw_ptr<WaylandKeyboard::Delegate> key_delegate_;

  // Delegate IME-specific events to be handled by //ui code.
  const raw_ptr<LinuxInputMethodContextDelegate> ime_delegate_;

  // Window obtained from IME delegate's widget. This WaylandInputMethodContext
  // will be associated exclusively with this window and so this object will not
  // change for the lifetime of the window.
  base::WeakPtr<WaylandWindow> window_;
  std::unique_ptr<ZwpTextInputV1Client> text_input_v1_client_;
  std::unique_ptr<ZwpTextInputV3Client> text_input_v3_client_;
  raw_ptr<ZwpTextInputV1> text_input_v1_;
  raw_ptr<ZwpTextInputV3> text_input_v3_;

  // Tracks whether InputMethod in Chrome has some focus.
  bool focused_ = false;

  // Tracks whether the window associated with the input method is focused.
  bool window_focused_ = false;

  // Tracks whether a request to activate InputMethod is sent to wayland
  // compositor.
  bool activated_ = false;

  // Cache of current TextInputClient's attributes.
  TextInputClientAttributes attributes_;

  // An object to compose a character from a sequence of key presses
  // including dead key etc.
  CharacterComposer character_composer_;

  // Stores the parameters required for OnDeleteSurroundingText.
  // The index moved by SetSurroundingText due to the maximum length of wayland
  // messages limitation. It is specified as 4000 bytes in the protocol spec of
  // text-input-unstable-v3.
  // This is byte-offset in UTF8 form.
  size_t surrounding_text_offset_ = 0;

  // Tracks the surrounding text. Surrounding text and its selection is NOT
  // trimmed by the wayland message size limitation in SurroundingTextTracker.
  SurroundingTextTracker surrounding_text_tracker_;

  // Whether the next CommitString should be treated as part of a
  // ConfirmCompositionText operation which keeps the current selection. This
  // allows ConfirmCompositionText to be implemented as an atomic operation
  // using CursorPosition and CommitString.
  bool pending_keep_selection_ = false;

  // Caches VirtualKeyboard visibility.
  bool virtual_keyboard_visible_ = false;

  // Cached desktop environment obtained from env.
  base::nix::DesktopEnvironment desktop_environment_;

  // Stores whether an invalid cursor end is sent by compositor, in which
  // case cursor end values should be ignored in preedit string.
  bool compositor_sends_invalid_cursor_end_ = false;

  // Keeps track of past text input clients to forward virtual keyboard changes
  // to, since unfocusing text inputs will detach clients immediately, but the
  // virtual keyboard bounds updates come later.
  // Using map instead of set, because WeakPtr doesn't support comparison.
  base::flat_map<TextInputClient*, base::WeakPtr<TextInputClient>>
      past_clients_;

  // Keeps modifiers_map sent from the wayland compositor.
  std::vector<std::string> modifiers_map_;
};

}  // namespace ui

#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_INPUT_METHOD_CONTEXT_H_