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 client about changes in clientPreedit
209  *
210  * @param forceUpdate force update even if preedit's emptiness is not
211  * changed.
212  * @see InputPanel::clientPreedit
213  * @since 5.1.23
214  */
215  void updatePreedit(bool forceUpdate);
216 
217  /**
218  * Notifies UI about changes in user interface.
219  *
220  * @param component The components of UI that need to be updated.
221  * @param immediate immediately flush the update to UI.
222  *
223  * @see UserInterfaceComponent InputPanel StatusArea
224  */
225  void updateUserInterface(UserInterfaceComponent component,
226  bool immediate = false);
227 
228  /**
229  * Prevent event deliver to input context, and re-send the event later.
230  *
231  * This should be only used by frontend to make sync and async event handled
232  * in the same order.
233  *
234  * @param block block state of input context.
235  *
236  * @see InputContextEventBlocker
237  */
238  void setBlockEventToClient(bool block);
239  bool hasPendingEvents() const;
240 
241  /**
242  * Has pending event that need to use key order fix.
243  *
244  * If pending event only have preedit, then it's generally fine to not use
245  * key forward.
246  *
247  * @since 5.0.21
248  */
249  bool hasPendingEventsStrictOrder() const;
250 
251  /// Returns the input context property by name.
252  InputContextProperty *property(const std::string &name);
253 
254  /// Returns the input context property by factory.
255  InputContextProperty *property(const InputContextPropertyFactory *factory);
256 
257  /// Returns the associated input panel.
258  InputPanel &inputPanel();
259 
260  /**
261  * Returns the associated input panel.
262  *
263  * @since 5.0.22
264  */
265  const InputPanel &inputPanel() const;
266 
267  /// Returns the associated StatusArea.
268  StatusArea &statusArea();
269 
270  /**
271  * Returns the associated StatusArea.
272  *
273  * @since 5.0.22
274  */
275  const StatusArea &statusArea() const;
276 
277  /**
278  * Helper function to return the input context property in specific type.
279  *
280  * @param T type of the input context property.
281  * @param name name of the input context property.
282  * @return T*
283  */
284  template <typename T>
285  T *propertyAs(const std::string &name) {
286  return static_cast<T *>(property(name));
287  }
288 
289  /**
290  * Helper function to return the input context property in specific type by
291  * given factory.
292  *
293  * @param T type of the input context property factory.
294  * @param name name of the input context property.
295  * @return T*
296  */
297  template <typename T>
298  typename T::PropertyType *propertyFor(const T *factory) {
299  return static_cast<typename T::PropertyType *>(property(factory));
300  }
301 
302  /**
303  * Notifies the change of a given input context property
304  *
305  * @param name name of the input context property.
306  *
307  * @see InputContextProperty::copyTo
308  */
309  void updateProperty(const std::string &name);
310 
311  /**
312  * Notifies the change of a given input context property by its factory.
313  *
314  * @param name name of the input context property.
315  *
316  * @see InputContextProperty::copyTo
317  */
318  void updateProperty(const InputContextPropertyFactory *factory);
319 
320  bool isVirtualKeyboardVisible() const;
321 
322  void showVirtualKeyboard() const;
323 
324  void hideVirtualKeyboard() const;
325 
326  bool clientControlVirtualkeyboardShow() const;
327 
328  void setClientControlVirtualkeyboardShow(bool show);
329 
330  bool clientControlVirtualkeyboardHide() const;
331 
332  void setClientControlVirtualkeyboardHide(bool hide);
333 
334 protected:
335  /**
336  * Send the committed string to client
337  *
338  * @param text string
339  *
340  * @see commitString
341  */
342  virtual void commitStringImpl(const std::string &text) = 0;
343 
344  /**
345  * Send the delete Surrounding Text request to client.
346  *
347  * @param offset offset of deletion start, in UCS4 char.
348  * @param size length of the deletion in UCS4 char.
349  */
350  virtual void deleteSurroundingTextImpl(int offset, unsigned int size) = 0;
351 
352  /**
353  * Send the forwarded key to client
354  *
355  * @see forwardKey
356  */
357  virtual void forwardKeyImpl(const ForwardKeyEvent &key) = 0;
358 
359  /**
360  * Send the preedit update to the client.
361  *
362  * @see updatePreedit
363  */
364  virtual void updatePreeditImpl() = 0;
365 
366  /**
367  * Send the UI update to client.
368  *
369  * @see CapabilityFlag::ClientSideUI
370  */
371  virtual void updateClientSideUIImpl();
372 
373  /// Notifies the destruction of the input context. Need to be called in the
374  /// destructor.
375  void destroy();
376 
377  /// Notifies the creation of input context. Need to be called at the end of
378  /// the constructor.
379  void created();
380 
381 private:
382  void setHasFocus(bool hasFocus);
383 
384  std::unique_ptr<InputContextPrivate> d_ptr;
385  FCITX_DECLARE_PRIVATE(InputContext);
386 };
387 
388 class FCITXCORE_EXPORT InputContextV2 : public InputContext {
389  friend class InputContextPrivate;
390 
391 public:
392  using InputContext::InputContext;
393  ~InputContextV2() override;
394 
395 protected:
396  virtual void commitStringWithCursorImpl(const std::string &text,
397  size_t cursor) = 0;
398 };
399 
400 /**
401  * A helper class for frontend addon. It use RAII to call
402  * setBlockEventToClient(true) in constructor and setBlockEventToClient(false)
403  * in destructor.
404  *
405  */
406 class FCITXCORE_EXPORT InputContextEventBlocker {
407 public:
408  InputContextEventBlocker(InputContext *inputContext);
410 
411 private:
413 };
414 
415 } // namespace fcitx
416 
417 #endif // _FCITX_INPUTCONTEXT_H_
Utility class provides a weak reference to the object.
Describe a Key in fcitx.
Definition: key.h:42
T::PropertyType * propertyFor(const T *factory)
Helper function to return the input context property in specific type by given factory.
Definition: inputcontext.h:298
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:285
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:51
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:406
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.