Fcitx
inputcontext.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 
8 #ifndef _FCITX_INPUTCONTEXT_H_
9 #define _FCITX_INPUTCONTEXT_H_
10 
11 #include <array>
12 #include <cstddef>
13 #include <cstdint>
14 #include <functional>
15 #include <memory>
16 #include <string>
17 #include <string_view>
19 #include <fcitx-utils/key.h>
20 #include <fcitx-utils/macros.h>
21 #include <fcitx-utils/rect.h>
23 #include <fcitx/event.h>
24 #include <fcitx/fcitxcore_export.h>
26 #include <fcitx/surroundingtext.h>
27 #include <fcitx/userinterface.h>
28 
29 /// \addtogroup FcitxCore
30 /// \{
31 /// \file
32 /// \brief Input Context for Fcitx.
33 
34 namespace fcitx {
35 using ICUUID = std::array<uint8_t, 16>;
36 
37 class InputContextManager;
38 class FocusGroup;
39 class InputContextPrivate;
40 class InputContextProperty;
41 class InputPanel;
42 class StatusArea;
43 using InputContextVisitor = std::function<bool(InputContext *ic)>;
44 
45 /**
46  * An input context represents a client of Fcitx. It can be a Window, or a text
47  * field depending on the application.
48  *
49  */
50 class FCITXCORE_EXPORT InputContext : public TrackableObject<InputContext> {
51  friend class InputContextManagerPrivate;
52  friend class FocusGroup;
53  friend class UserInterfaceManager;
54  friend class UserInterfaceManagerPrivate;
55 
56 public:
57  InputContext(InputContextManager &manager, const std::string &program = {});
58  virtual ~InputContext();
59  InputContext(InputContext &&other) = delete;
60 
61  /// Returns the underlying implementation of Input Context.
62  virtual const char *frontend() const = 0;
63 
64  /**
65  * Return the frontend name.
66  *
67  * Helper function that simply calls InputContext::frontend, but returns a
68  * string_view.
69  *
70  * @since 5.0.22
71  */
72  std::string_view frontendName() const;
73 
74  /// Returns the uuid of this input context.
75  const ICUUID &uuid() const;
76 
77  /// Returns the program name of input context. It can be empty depending on
78  /// the application.
79  const std::string &program() const;
80 
81  /// Returns the display server of the client. In form of type:string, E.g.
82  /// client from X11 server of :0 will become x11::0.
83  std::string display() const;
84 
85  /// Returns the cursor position of the client.
86  const Rect &cursorRect() const;
87 
88  /// Return the client scale factor.
89  double scaleFactor() const;
90 
91  // Following functions should only be called by Frontend.
92  // Calling following most of following functions will generate a
93  // corresponding InputContextEvent.
94 
95  /// Called When input context gains the input focus.
96  void focusIn();
97 
98  /// Called when input context losts the input focus.
99  void focusOut();
100 
101  /**
102  * Set the focus group of this input context. group can be null if it does
103  * not belong to any group.
104  *
105  * @see FocusGroup
106  */
107  void setFocusGroup(FocusGroup *group);
108 
109  /// Returns the current focus group of input context.
110  FocusGroup *focusGroup() const;
111 
112  /// Called when input context state need to be reset.
113  FCITXCORE_DEPRECATED void reset(ResetReason reason);
114 
115  /// Called when input context state need to be reset. Input context need to
116  /// have focus.
117  void reset();
118 
119  /**
120  * Update the capability flags of the input context.
121  *
122  * @see CapabilityFlag
123  */
124  void setCapabilityFlags(CapabilityFlags flags);
125 
126  /**
127  * Returns the current capability flags
128  *
129  * @see CapabilityFlag
130  */
131  CapabilityFlags capabilityFlags() const;
132 
133  /// Override the preedit hint from client.
134  void setEnablePreedit(bool enable);
135 
136  /// Check if preedit is manually disabled.
137  bool isPreeditEnabled() const;
138 
139  /// Update the current cursor rect of the input context.
140  void setCursorRect(Rect rect);
141 
142  /// Update the client rect with scale factor.
143  void setCursorRect(Rect rect, double scale);
144 
145  /// Send a key event to current input context.
146  bool keyEvent(KeyEvent &event);
147 
148  /**
149  * Send a virtual keyboard event to current input context.
150  *
151  * @param event virtual keyboard event
152  * @return whether event is accepted.
153  * @since 5.1.0
154  */
155  bool virtualKeyboardEvent(VirtualKeyboardEvent &event);
156 
157  /// Returns whether the input context holds the input focus. Input context
158  /// need to have focus.
159  bool hasFocus() const;
160 
161  /// Invoke an action on the preedit
162  void invokeAction(InvokeActionEvent &event);
163 
164  /**
165  * Returns the mutable surrounding text of the input context.
166  *
167  * updateSurroundingText() need to be called after changes by frontend.
168  *
169  * @see InputContext::updateSurroundingText SurroundingText
170  */
171  SurroundingText &surroundingText();
172 
173  /// Returns the immutable surrounding text of the input context.
174  const SurroundingText &surroundingText() const;
175 
176  /// Notifies the surrounding text modification from the client.
177  void updateSurroundingText();
178 
179  // Following functions are invoked by input method or misc modules to send
180  // event to the corresponding client.
181  /// Commit a string to the client.
182  void commitString(const std::string &text);
183 
184  /**
185  * Commit a string to application with a cursor location after commit.
186  *
187  * @param text text to commit
188  * @param cursor cursor position after commit, the value should be within
189  * [0, utf8::length(text)].
190  * @see CapabilityFlag::CommitStringWithCursor
191  */
192  void commitStringWithCursor(const std::string &text, size_t cursor);
193 
194  /// Ask client to delete a range of surrounding text.
195  void deleteSurroundingText(int offset, unsigned int size);
196 
197  /// Send a key event to client.
198  void forwardKey(const Key &rawKey, bool isRelease = false, int time = 0);
199 
200  /**
201  * Notifies client about changes in clientPreedit
202  *
203  * @see InputPanel::clientPreedit
204  */
205  void updatePreedit();
206 
207  /**
208  * Notifies UI about changes in user interface.
209  *
210  * @param component The components of UI that need to be updated.
211  * @param immediate immediately flush the update to UI.
212  *
213  * @see UserInterfaceComponent InputPanel StatusArea
214  */
215  void updateUserInterface(UserInterfaceComponent component,
216  bool immediate = false);
217 
218  /**
219  * Prevent event deliver to input context, and re-send the event later.
220  *
221  * This should be only used by frontend to make sync and async event handled
222  * in the same order.
223  *
224  * @param block block state of input context.
225  *
226  * @see InputContextEventBlocker
227  */
228  void setBlockEventToClient(bool block);
229  bool hasPendingEvents() const;
230 
231  /**
232  * Has pending event that need to use key order fix.
233  *
234  * If pending event only have preedit, then it's generally fine to not use
235  * key forward.
236  *
237  * @since 5.0.21
238  */
239  bool hasPendingEventsStrictOrder() const;
240 
241  /// Returns the input context property by name.
242  InputContextProperty *property(const std::string &name);
243 
244  /// Returns the input context property by factory.
245  InputContextProperty *property(const InputContextPropertyFactory *factory);
246 
247  /// Returns the associated input panel.
248  InputPanel &inputPanel();
249 
250  /**
251  * Returns the associated input panel.
252  *
253  * @since 5.0.22
254  */
255  const InputPanel &inputPanel() const;
256 
257  /// Returns the associated StatusArea.
258  StatusArea &statusArea();
259 
260  /**
261  * Returns the associated StatusArea.
262  *
263  * @since 5.0.22
264  */
265  const StatusArea &statusArea() const;
266 
267  /**
268  * Helper function to return the input context property in specific type.
269  *
270  * @param T type of the input context property.
271  * @param name name of the input context property.
272  * @return T*
273  */
274  template <typename T>
275  T *propertyAs(const std::string &name) {
276  return static_cast<T *>(property(name));
277  }
278 
279  /**
280  * Helper function to return the input context property in specific type by
281  * given factory.
282  *
283  * @param T type of the input context property factory.
284  * @param name name of the input context property.
285  * @return T*
286  */
287  template <typename T>
288  typename T::PropertyType *propertyFor(const T *factory) {
289  return static_cast<typename T::PropertyType *>(property(factory));
290  }
291 
292  /**
293  * Notifies the change of a given input context property
294  *
295  * @param name name of the input context property.
296  *
297  * @see InputContextProperty::copyTo
298  */
299  void updateProperty(const std::string &name);
300 
301  /**
302  * Notifies the change of a given input context property by its factory.
303  *
304  * @param name name of the input context property.
305  *
306  * @see InputContextProperty::copyTo
307  */
308  void updateProperty(const InputContextPropertyFactory *factory);
309 
310  bool isVirtualKeyboardVisible() const;
311 
312  void showVirtualKeyboard() const;
313 
314  void hideVirtualKeyboard() const;
315 
316  bool clientControlVirtualkeyboardShow() const;
317 
318  void setClientControlVirtualkeyboardShow(bool show);
319 
320  bool clientControlVirtualkeyboardHide() const;
321 
322  void setClientControlVirtualkeyboardHide(bool hide);
323 
324 protected:
325  /**
326  * Send the committed string to client
327  *
328  * @param text string
329  *
330  * @see commitString
331  */
332  virtual void commitStringImpl(const std::string &text) = 0;
333 
334  /**
335  * Send the delete Surrounding Text request to client.
336  *
337  * @param offset offset of deletion start, in UCS4 char.
338  * @param size length of the deletion in UCS4 char.
339  */
340  virtual void deleteSurroundingTextImpl(int offset, unsigned int size) = 0;
341 
342  /**
343  * Send the forwarded key to client
344  *
345  * @see forwardKey
346  */
347  virtual void forwardKeyImpl(const ForwardKeyEvent &key) = 0;
348 
349  /**
350  * Send the preedit update to the client.
351  *
352  * @see updatePreedit
353  */
354  virtual void updatePreeditImpl() = 0;
355 
356  /**
357  * Send the UI update to client.
358  *
359  * @see CapabilityFlag::ClientSideUI
360  */
361  virtual void updateClientSideUIImpl();
362 
363  /// Notifies the destruction of the input context. Need to be called in the
364  /// destructor.
365  void destroy();
366 
367  /// Notifies the creation of input context. Need to be called at the end of
368  /// the constructor.
369  void created();
370 
371 private:
372  void setHasFocus(bool hasFocus);
373 
374  std::unique_ptr<InputContextPrivate> d_ptr;
375  FCITX_DECLARE_PRIVATE(InputContext);
376 };
377 
378 class FCITXCORE_EXPORT InputContextV2 : public InputContext {
379  friend class InputContextPrivate;
380 
381 public:
382  using InputContext::InputContext;
383  ~InputContextV2() override;
384 
385 protected:
386  virtual void commitStringWithCursorImpl(const std::string &text,
387  size_t cursor) = 0;
388 };
389 
390 /**
391  * A helper class for frontend addon. It use RAII to call
392  * setBlockEventToClient(true) in constructor and setBlockEventToClient(false)
393  * in destructor.
394  *
395  */
396 class FCITXCORE_EXPORT InputContextEventBlocker {
397 public:
398  InputContextEventBlocker(InputContext *inputContext);
400 
401 private:
403 };
404 
405 } // namespace fcitx
406 
407 #endif // _FCITX_INPUTCONTEXT_H_
Utility class provides a weak reference to the object.
Describe a Key in fcitx.
Definition: key.h:41
T::PropertyType * propertyFor(const T *factory)
Helper function to return the input context property in specific type by given factory.
Definition: inputcontext.h:288
Utitliy classes for statically tracking the life of a object.
Definition: action.cpp:17
T * propertyAs(const std::string &name)
Helper function to return the input context property in specific type.
Definition: inputcontext.h:275
Local cache for surrounding text.
Provide utility to handle rectangle.
Enum type for input context capability.
Input Panel is usually a floating window that is display at the cursor of input.
Definition: inputpanel.h:48
Base class for User Interface addon.
Class represents the current state of surrounding text of an input context.
A helper class for frontend addon.
Definition: inputcontext.h:396
Helper class to be used with TrackableObjectReference.
UserInterfaceComponent
Definition: userinterface.h:21
Status area represent a list of actions and action may have sub actions.
Definition: statusarea.h:44
Factory class for input context property.
Class provides bit flag support for Enum.
Definition: flags.h:33
Input Method event for Fcitx.
Input Context Property for Fcitx.
An input context represents a client of Fcitx.
Definition: inputcontext.h:50
Class to represent a key.
This is a class that designed to store state that is specific to certain input context.