Fcitx
instance.h
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_INSTANCE_H_
8 #define _FCITX_INSTANCE_H_
9 
10 #include <exception>
11 #include <memory>
12 #include <string>
13 #include <utility>
15 #include <fcitx-utils/eventdispatcher.h>
16 #include <fcitx-utils/handlertable.h>
17 #include <fcitx-utils/macros.h>
18 #include <fcitx/event.h>
19 #include <fcitx/fcitxcore_export.h>
20 #include <fcitx/globalconfig.h>
21 #include <fcitx/text.h>
22 
23 #define FCITX_INVALID_COMPOSE_RESULT 0xffffffff
24 
25 namespace fcitx {
26 
27 class InputContext;
28 class InstancePrivate;
29 class EventLoop;
30 class AddonManager;
31 class InputContextManager;
32 class InputMethodManager;
33 class InputMethodEngine;
34 class InputMethodEntry;
35 class TempModeManager;
36 class UserInterfaceManager;
37 class GlobalConfig;
38 class FocusGroup;
39 
40 using EventHandler = std::function<void(Event &event)>;
41 
42 /**
43  * The function mode of virtual keyboard.
44  */
45 enum class VirtualKeyboardFunctionMode : uint32_t { Full = 1, Limited = 2 };
46 
47 /**
48  * The event handling phase of event pipeline.
49  */
50 enum class EventWatcherPhase {
51  /**
52  * Handler executed before input method.
53  *
54  * Useful for addons that want to implement an independent mode.
55  *
56  * A common workflow of such addon is:
57  * 1. Check a hotkey in PostInputMethod phase to trigger the mode
58  * 2. Handle all the key event in PreInputMethod phase just like regular
59  * input method.
60  */
61  PreInputMethod,
62  /**
63  * Handlers to be executed right after input method.
64  *
65  * The input method keyEvent is registered with an internal handler. So all
66  * the new handler in this phase will still executed after input method.
67  */
68  InputMethod,
69  /**
70  * Handlers to be executed after input method.
71  *
72  * common use case is when you want to implement a key that triggers a
73  * standalone action.
74  */
75  PostInputMethod,
76  /// Internal phase to be executed first
77  ReservedFirst,
78  /// Internal phase to be executed last
79  ReservedLast,
80  Default = PostInputMethod
81 };
82 
83 struct FCITXCORE_EXPORT InstanceQuietQuit : public std::exception {};
84 
85 /**
86  * An instance represents a standalone Fcitx instance. Usually there is only one
87  * of such object.
88  *
89  * Fcitx Instance provides the access to all the addons and sub components. It
90  * also provides a event pipeline for handling input method related event.
91  */
92 class FCITXCORE_EXPORT Instance : public ConnectableObject {
93 public:
94  /**
95  * A main function like construct to be used to create Fcitx Instance.
96  *
97  * For more details, see --help of fcitx5 command.
98  *
99  * @param argc number of argument
100  * @param argv command line arguments
101  */
102  Instance(int argc, char *argv[]);
103 
104  ~Instance();
105 
106  bool initialized() const { return !!d_ptr; }
107 
108  /**
109  * Set the pipe forwarding unix signal information.
110  *
111  * Fcitx Instance is running within its own thread, usually main thread. In
112  * order to make it handle signal correctly in a thread-safe way, it is
113  * possible to set a file descriptor that write the signal number received
114  * by the signal handler. Usually this is done through a self-pipe. This is
115  * already handled by Fcitx default server implementation, normal addon user
116  * should not touch this. The common usecase is when you want to embed Fcitx
117  * into your own program.
118  *
119  * @param fd file descriptor
120  */
121  void setSignalPipe(int fd);
122 
123  /**
124  * Start the event loop of Fcitx.
125  *
126  * @return return value that can be used as main function return code.
127  */
128  int exec();
129 
130  /**
131  * Check whether command line specify if it will replace an existing fcitx
132  * server.
133  *
134  * This function is only useful if your addon provides a way to replace
135  * existing fcitx server. Basically it is checking whether -r is passed to
136  * fcitx command line.
137  *
138  * @return whether to replace existing fcitx server. Default value is false.
139  */
140  bool willTryReplace() const;
141 
142  /**
143  * Check whether command line specify whether to keep fcitx running.
144  *
145  * There could be multiple display server, such as X/Wayland/etc. Fcitx
146  * usually will exit when the connection is closed. Command line -k can
147  * override this behavior and keep Fcitx running.
148  *
149  * @return whether to exit after main display is disconnected.
150  */
151  bool exitWhenMainDisplayDisconnected() const;
152 
153  /**
154  * Check whether fcitx is in exiting process.
155  *
156  * @return
157  */
158  bool exiting() const;
159 
160  /// Get the fcitx event loop.
161  EventLoop &eventLoop();
162 
163  /**
164  * Return a shared event dispatcher that is already attached to instance's
165  * event loop.
166  *
167  * @return shared event dispatcher.
168  * @since 5.1.9
169  */
170  EventDispatcher &eventDispatcher();
171 
172  /// Get the addon manager.
173  AddonManager &addonManager();
174 
175  /// Get the input context manager
176  InputContextManager &inputContextManager();
177 
178  /// Get the user interface manager
179  UserInterfaceManager &userInterfaceManager();
180 
181  /// Get the input method manager
182  InputMethodManager &inputMethodManager();
183 
184  /// Get the input method manager
185  const InputMethodManager &inputMethodManager() const;
186 
187  /// Get the temporary mode manager.
188  TempModeManager &tempModeManager();
189 
190  /// Get the global config.
191  GlobalConfig &globalConfig();
192 
193  // TODO: Merge this when we can break API.
194  bool postEvent(Event &event);
195  bool postEvent(Event &&event) { return postEvent(event); }
196 
197  /**
198  * Put a event to the event pipe line.
199  *
200  * @param event Input method event
201  * @return return the value of event.accepted()
202  */
203  bool postEvent(Event &event) const;
204  bool postEvent(Event &&event) const { return postEvent(event); }
205 
206  /**
207  * Add a callback to for certain event type.
208  *
209  * @param type event type
210  * @param phase the stage that callback will be executed.
211  * @param callback callback function.
212  * @return Handle to the callback, the callback will be removed when it is
213  * deleted.
214  */
215  FCITX_NODISCARD std::unique_ptr<HandlerTableEntry<EventHandler>>
216  watchEvent(EventType type, EventWatcherPhase phase, EventHandler callback);
217 
218  template <EventType T, typename Callback>
219  FCITX_NODISCARD std::unique_ptr<HandlerTableEntry<EventHandler>>
220  watchEvent(EventWatcherPhase phase, Callback &&callback) {
221  return watchEvent(T, phase,
222  [callback = std::forward<Callback>(callback)](
223  Event &event) mutable {
224  callback(static_cast<EventFor<T> &>(event));
225  });
226  }
227 
228  /// Return the unique name of input method for given input context.
229  std::string inputMethod(InputContext *ic);
230 
231  /// Return the input method entry for given input context.
232  const InputMethodEntry *inputMethodEntry(InputContext *ic);
233 
234  /// Return the input method engine object for given input context.
235  InputMethodEngine *inputMethodEngine(InputContext *ic);
236 
237  /// Return the input method engine object for given unique input method
238  /// name.
239  InputMethodEngine *inputMethodEngine(const std::string &name);
240 
241  /**
242  * Return the input method icon for input context.
243  *
244  * It will fallback to input-keyboard by default if no input method is
245  * available.
246  *
247  * @param ic input context
248  * @return icon name.
249  *
250  * @see InputMethodEngine::subModeIcon
251  */
252  std::string inputMethodIcon(InputContext *ic);
253 
254  /**
255  * Return the input method label for input context.
256  *
257  * @param ic input context
258  * @return label.
259  *
260  * @see InputMethodEngine::subModeLabel
261  * @since 5.0.11
262  */
263  std::string inputMethodLabel(InputContext *ic);
264 
265  /**
266  * Handle current XCompose state.
267  *
268  * @param ic input context.
269  * @param keysym key symbol.
270  *
271  * @return unicode
272  *
273  * @see processComposeString
274  */
275  FCITXCORE_DEPRECATED uint32_t processCompose(InputContext *ic,
276  KeySym keysym);
277 
278  /**
279  * Handle current XCompose state.
280  *
281  * @param ic input context.
282  * @param keysym key symbol.
283  *
284  * @return the composed string, if it returns nullopt, it means compose is
285  * invalid.
286  *
287  * @see processComposeString
288  * @since 5.0.4
289  */
290  std::optional<std::string> processComposeString(InputContext *ic,
291  KeySym keysym);
292 
293  /// Reset the compose state.
294  void resetCompose(InputContext *inputContext);
295 
296  /// Check whether input context is composing or not.
297  bool isComposing(InputContext *inputContext);
298 
299  /**
300  * Update the commit string to frontend
301  *
302  * This function should be not be used directly since it is already used
303  * internally by InputContext::commitString.
304  *
305  * @param inputContext input context
306  * @param orig original string
307  * @return the updated string.
308  * @see InputContext::commitString
309  */
310  std::string commitFilter(InputContext *inputContext,
311  const std::string &orig);
312  /**
313  * Update the string that will be displayed in user interface.
314  *
315  * This function should only be used by frontend for client preedit, or user
316  * interface, for the other field in input panel.
317  *
318  * @see InputPanel
319  *
320  * @param inputContext input context
321  * @param orig orig text
322  * @return fcitx::Text
323  */
324  Text outputFilter(InputContext *inputContext, const Text &orig);
325 
326  FCITX_DECLARE_SIGNAL(Instance, CommitFilter,
327  void(InputContext *inputContext, std::string &orig));
328  FCITX_DECLARE_SIGNAL(Instance, OutputFilter,
329  void(InputContext *inputContext, Text &orig));
330  FCITX_DECLARE_SIGNAL(Instance, KeyEventResult,
331  void(const KeyEvent &keyEvent));
332  /**
333  * \deprecated
334  */
336 
337  /// Return a focused input context.
338  InputContext *lastFocusedInputContext();
339  /// Return the most recent focused input context. If there isn't such ic,
340  /// return the last unfocused input context.
341  InputContext *mostRecentInputContext();
342 
343  /// All user interface update is batched internally. This function will
344  /// flush all the batched UI update immediately.
345  void flushUI();
346 
347  // controller functions.
348 
349  /// Exit the fcitx event loop
350  void exit();
351 
352  /// Exit the fcitx event loop with an exit code.
353  void exit(int exitCode);
354 
355  /// Restart fcitx instance, this should only be used within a regular Fcitx
356  /// server, not within embedded mode.
357  void restart();
358 
359  /// Launch configtool
360  void configure();
361 
362  FCITXCORE_DEPRECATED void configureAddon(const std::string &addon);
363  FCITXCORE_DEPRECATED void configureInputMethod(const std::string &imName);
364 
365  /// Return the name of current user interface addon.
366  std::string currentUI();
367 
368  /// Return the addon name of given input method.
369  std::string addonForInputMethod(const std::string &imName);
370 
371  // Following functions are operations against lastFocusedInputContext
372 
373  /// Activate last focused input context. (Switch to the active input method)
374  void activate();
375 
376  /// Deactivate last focused input context. (Switch to the first input
377  /// method)
378  void deactivate();
379 
380  /// Toggle between the first input method and active input method.
381  void toggle();
382 
383  /// Reset the input method configuration and recreate based on system
384  /// language.
385  void resetInputMethodList();
386 
387  /// Return a fcitx5-remote compatible value for the state.
388  int state();
389 
390  /// Reload global config.
391  void reloadConfig();
392  /// Reload certain addon config.
393  void reloadAddonConfig(const std::string &addonName);
394  /// Load newly installed input methods and addons.
395  void refresh();
396 
397  /// Return the current input method of last focused input context.
398  std::string currentInputMethod();
399 
400  /// Set the input method of last focused input context.
401  void setCurrentInputMethod(const std::string &imName);
402 
403  /**
404  * Set the input method of given input context.
405  *
406  * The input method need to be within the current group. Local parameter can
407  * be used to set the input method only for this input context.
408  *
409  * @param ic input context
410  * @param imName unique name of a input method
411  * @param local
412  */
413  void setCurrentInputMethod(InputContext *ic, const std::string &imName,
414  bool local);
415 
416  /*
417  * Enumerate input method group
418  *
419  * This function has different behavior comparing to
420  * InputMethodManager::enumerateGroup Do not use this..
421  */
422  FCITXCORE_DEPRECATED
423  bool enumerateGroup(bool forward);
424 
425  /// Enumerate input method with in current group
426  void enumerate(bool forward);
427 
428  /**
429  * Get the default focus group with given display hint.
430  *
431  * This function is used by frontend to assign a focus group from an unknown
432  * display server.
433  *
434  * @param displayHint Display server hint, it can something like be x11: /
435  * wayland:
436  * @return focus group
437  */
438  FocusGroup *defaultFocusGroup(const std::string &displayHint = {});
439 
440  /**
441  * Set xkb RLVMO tuple for given display
442  *
443  * @param display display name
444  * @param rule xkb rule name
445  * @param model xkb model name
446  * @param options xkb option
447  */
448  void setXkbParameters(const std::string &display, const std::string &rule,
449  const std::string &model, const std::string &options);
450 
451  /// Update xkb state mask for given display
452  void updateXkbStateMask(const std::string &display, uint32_t depressed_mods,
453  uint32_t latched_mods, uint32_t locked_mods);
454 
455  /// Clear xkb state mask for given display
456  void clearXkbStateMask(const std::string &display);
457 
458  /**
459  * Show a small popup with input popup window with current input method
460  * information.
461  *
462  * The popup will be hidden after certain amount of time.
463  *
464  * This is useful for input method that has multiple sub modes. It can be
465  * called with switching sub modes within the input method.
466  *
467  * The behavior is controlled by global config.
468  *
469  * @param ic input context.
470  */
471  void showInputMethodInformation(InputContext *ic);
472 
473  /**
474  * Show a small popup with input popup window with current input method
475  * information.
476  *
477  * The popup will be hidden after certain amount of time. The popup will
478  * always be displayed, regardless of the showInputMethodInformation in
479  * global config.
480  *
481  * This is useful for input method that has internal switches.
482  *
483  * @param ic input context.
484  * @param message message string to be displayed
485  * @since 5.1.11
486  */
487  void showCustomInputMethodInformation(InputContext *ic,
488  const std::string &message);
489 
490  /**
491  * Check if need to invoke Instance::refresh.
492  *
493  * @return need update
494  * @see Instance::refresh
495  */
496  bool checkUpdate() const;
497 
498  /// Return the version string of Fcitx.
499  static const char *version();
500 
501  /**
502  * Save everything including input method profile and addon data.
503  *
504  * It also reset the idle save timer.
505  *
506  * @since 5.0.14
507  */
508  void save();
509 
510  /**
511  * Initialize fcitx.
512  *
513  * This is only intended to be used if you want to handle event loop on your
514  * own. Otherwise you should use Instance::exec().
515  *
516  * @since 5.0.14
517  */
518  void initialize();
519 
520  /**
521  * Let other know that event loop is already running.
522  *
523  * This should only be used if you run event loop on your own.
524  * @since 5.0.14
525  */
526  void setRunning(bool running);
527 
528  /**
529  * Whether event loop is started and still running.
530  * @since 5.0.14
531  */
532  bool isRunning() const;
533 
534  /**
535  * The current global input method mode.
536  *
537  * It may affect the user interface and behavior of certain key binding.
538  * @since 5.1.0
539  */
540  InputMethodMode inputMethodMode() const;
541 
542  /**
543  * Set the current global input method mode.
544  *
545  * @see InputMethodMode
546  * @see InputMethodModeChanged
547  * @since 5.1.0
548  */
549  void setInputMethodMode(InputMethodMode mode);
550 
551  /**
552  * Whether restart is requested.
553  * @since 5.0.18
554  */
555  bool isRestartRequested() const;
556 
557  bool virtualKeyboardAutoShow() const;
558 
559  void setVirtualKeyboardAutoShow(bool autoShow);
560 
561  bool virtualKeyboardAutoHide() const;
562 
563  void setVirtualKeyboardAutoHide(bool autoHide);
564 
565  VirtualKeyboardFunctionMode virtualKeyboardFunctionMode() const;
566 
567  void setVirtualKeyboardFunctionMode(VirtualKeyboardFunctionMode mode);
568 
569  /**
570  * Set if this instance is running as fcitx5 binary.
571  *
572  * This will affect return value of Instance::canRestart.
573  *
574  * @see Instance::canRestart
575  * @since 5.1.6
576  */
577  void setBinaryMode();
578 
579  /**
580  * Check if fcitx 5 can safely restart by itself.
581  *
582  * When the existing fcitx 5 instance returns false, fcitx5 -r, or
583  * Instance::restart will just be no-op.
584  *
585  * @return whether it is safe for fcitx to restart on its own.
586  * @see AddonInstance::setCanRestart
587  * @since 5.1.6
588  */
589  bool canRestart() const;
590 
591 protected:
592  // For testing purpose
593  InstancePrivate *privateData();
594 
595 private:
596  void handleSignal();
597 
598  bool canTrigger() const;
599  bool canAltTrigger(InputContext *ic) const;
600  bool canEnumerate(InputContext *ic) const;
601  bool canChangeGroup() const;
602  bool trigger(InputContext *ic, bool totallyReleased);
603  bool altTrigger(InputContext *ic);
604  bool activate(InputContext *ic);
605  bool deactivate(InputContext *ic);
606  bool enumerate(InputContext *ic, bool forward);
607  bool toggle(InputContext *ic, InputMethodSwitchedReason reason =
609 
610  void activateInputMethod(InputContextEvent &event);
611  void deactivateInputMethod(InputContextEvent &event);
612 
613  std::unique_ptr<InstancePrivate> d_ptr;
614  FCITX_DECLARE_PRIVATE(Instance);
615 };
616 }; // namespace fcitx
617 
618 #endif // _FCITX_INSTANCE_H_
Base class for all object supports connection.
EventType
Type of input method events.
Definition: event.h:66
An instance represents a standalone Fcitx instance.
Definition: instance.h:92
Formatted string commonly used in user interface.
Manage registered TempMode objects for an Instance.
#define FCITX_DECLARE_SIGNAL(CLASS_NAME, NAME,...)
Declare signal by type.
InputMethodSwitchedReason
The reason why input method is switched to another.
Definition: event.h:42
Definition: action.cpp:17
Utilities to enable use object with signal.
A class represents a formatted string.
Definition: text.h:27
Class to manage all the input method relation information.
Base class for fcitx event.
Definition: event.h:225
A thread safe class to post event to a certain EventLoop.
CheckUpdateEvent is posted when the Instance is requested to check for newly installed addons and inp...
Input Method event for Fcitx.
An input context represents a client of Fcitx.
Definition: inputcontext.h:50