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