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));
336  Instance, XkbStateMaskChanged,
337  void(const std::string &display,
338  std::optional<std::tuple<uint32_t, uint32_t, uint32_t>> oldMask,
339  std::optional<std::tuple<uint32_t, uint32_t, uint32_t>> newMask));
340  /**
341  * \deprecated
342  */
344 
345  /// Return a focused input context.
346  InputContext *lastFocusedInputContext();
347  /// Return the most recent focused input context. If there isn't such ic,
348  /// return the last unfocused input context.
349  InputContext *mostRecentInputContext();
350 
351  /// All user interface update is batched internally. This function will
352  /// flush all the batched UI update immediately.
353  void flushUI();
354 
355  // controller functions.
356 
357  /// Exit the fcitx event loop
358  void exit();
359 
360  /// Exit the fcitx event loop with an exit code.
361  void exit(int exitCode);
362 
363  /// Restart fcitx instance, this should only be used within a regular Fcitx
364  /// server, not within embedded mode.
365  void restart();
366 
367  /// Launch configtool
368  void configure();
369 
370  FCITXCORE_DEPRECATED void configureAddon(const std::string &addon);
371  FCITXCORE_DEPRECATED void configureInputMethod(const std::string &imName);
372 
373  /// Return the name of current user interface addon.
374  std::string currentUI();
375 
376  /// Return the addon name of given input method.
377  std::string addonForInputMethod(const std::string &imName);
378 
379  // Following functions are operations against lastFocusedInputContext
380 
381  /// Activate last focused input context. (Switch to the active input method)
382  void activate();
383 
384  /// Deactivate last focused input context. (Switch to the first input
385  /// method)
386  void deactivate();
387 
388  /// Toggle between the first input method and active input method.
389  void toggle();
390 
391  /// Reset the input method configuration and recreate based on system
392  /// language.
393  void resetInputMethodList();
394 
395  /// Return a fcitx5-remote compatible value for the state.
396  int state();
397 
398  /// Reload global config.
399  void reloadConfig();
400  /// Reload certain addon config.
401  void reloadAddonConfig(const std::string &addonName);
402  /// Load newly installed input methods and addons.
403  void refresh();
404 
405  /// Return the current input method of last focused input context.
406  std::string currentInputMethod();
407 
408  /// Set the input method of last focused input context.
409  void setCurrentInputMethod(const std::string &imName);
410 
411  /**
412  * Set the input method of given input context.
413  *
414  * The input method need to be within the current group. Local parameter can
415  * be used to set the input method only for this input context.
416  *
417  * @param ic input context
418  * @param imName unique name of a input method
419  * @param local
420  */
421  void setCurrentInputMethod(InputContext *ic, const std::string &imName,
422  bool local);
423 
424  /*
425  * Enumerate input method group
426  *
427  * This function has different behavior comparing to
428  * InputMethodManager::enumerateGroup Do not use this..
429  */
430  FCITXCORE_DEPRECATED
431  bool enumerateGroup(bool forward);
432 
433  /// Enumerate input method with in current group
434  void enumerate(bool forward);
435 
436  /**
437  * Get the default focus group with given display hint.
438  *
439  * This function is used by frontend to assign a focus group from an unknown
440  * display server.
441  *
442  * @param displayHint Display server hint, it can something like be x11: /
443  * wayland:
444  * @return focus group
445  */
446  FocusGroup *defaultFocusGroup(const std::string &displayHint = {});
447 
448  /**
449  * Set xkb RLVMO tuple for given display
450  *
451  * @param display display name
452  * @param rule xkb rule name
453  * @param model xkb model name
454  * @param options xkb option
455  */
456  void setXkbParameters(const std::string &display, const std::string &rule,
457  const std::string &model, const std::string &options);
458 
459  /// Update xkb state mask for given display
460  void updateXkbStateMask(const std::string &display, uint32_t depressed_mods,
461  uint32_t latched_mods, uint32_t locked_mods);
462 
463  /// Clear xkb state mask for given display
464  void clearXkbStateMask(const std::string &display);
465 
466  /**
467  * Return xkb state mask for given display
468  *
469  * @see Instance::updateXkbStateMask
470  * @see Instance::clearXkbStateMask
471  * @see InputContext::display
472  * @param display display name
473  * @since 5.1.22
474  */
475  std::optional<std::tuple<uint32_t, uint32_t, uint32_t>>
476  xkbStateMask(const std::string &display) const;
477 
478  /**
479  * Show a small popup with input popup window with current input method
480  * information.
481  *
482  * The popup will be hidden after certain amount of time.
483  *
484  * This is useful for input method that has multiple sub modes. It can be
485  * called with switching sub modes within the input method.
486  *
487  * The behavior is controlled by global config.
488  *
489  * @param ic input context.
490  */
491  void showInputMethodInformation(InputContext *ic);
492 
493  /**
494  * Show a small popup with input popup window with current input method
495  * information.
496  *
497  * The popup will be hidden after certain amount of time. The popup will
498  * always be displayed, regardless of the showInputMethodInformation in
499  * global config.
500  *
501  * This is useful for input method that has internal switches.
502  *
503  * @param ic input context.
504  * @param message message string to be displayed
505  * @since 5.1.11
506  */
507  void showCustomInputMethodInformation(InputContext *ic,
508  const std::string &message);
509 
510  /**
511  * Check if need to invoke Instance::refresh.
512  *
513  * @return need update
514  * @see Instance::refresh
515  */
516  bool checkUpdate() const;
517 
518  /// Return the version string of Fcitx.
519  static const char *version();
520 
521  /**
522  * Save everything including input method profile and addon data.
523  *
524  * It also reset the idle save timer.
525  *
526  * @since 5.0.14
527  */
528  void save();
529 
530  /**
531  * Initialize fcitx.
532  *
533  * This is only intended to be used if you want to handle event loop on your
534  * own. Otherwise you should use Instance::exec().
535  *
536  * @since 5.0.14
537  */
538  void initialize();
539 
540  /**
541  * Let other know that event loop is already running.
542  *
543  * This should only be used if you run event loop on your own.
544  * @since 5.0.14
545  */
546  void setRunning(bool running);
547 
548  /**
549  * Whether event loop is started and still running.
550  * @since 5.0.14
551  */
552  bool isRunning() const;
553 
554  /**
555  * The current global input method mode.
556  *
557  * It may affect the user interface and behavior of certain key binding.
558  * @since 5.1.0
559  */
560  InputMethodMode inputMethodMode() const;
561 
562  /**
563  * Set the current global input method mode.
564  *
565  * @see InputMethodMode
566  * @see InputMethodModeChanged
567  * @since 5.1.0
568  */
569  void setInputMethodMode(InputMethodMode mode);
570 
571  /**
572  * Whether restart is requested.
573  * @since 5.0.18
574  */
575  bool isRestartRequested() const;
576 
577  bool virtualKeyboardAutoShow() const;
578 
579  void setVirtualKeyboardAutoShow(bool autoShow);
580 
581  bool virtualKeyboardAutoHide() const;
582 
583  void setVirtualKeyboardAutoHide(bool autoHide);
584 
585  VirtualKeyboardFunctionMode virtualKeyboardFunctionMode() const;
586 
587  void setVirtualKeyboardFunctionMode(VirtualKeyboardFunctionMode mode);
588 
589  /**
590  * Set if this instance is running as fcitx5 binary.
591  *
592  * This will affect return value of Instance::canRestart.
593  *
594  * @see Instance::canRestart
595  * @since 5.1.6
596  */
597  void setBinaryMode();
598 
599  /**
600  * Check if fcitx 5 can safely restart by itself.
601  *
602  * When the existing fcitx 5 instance returns false, fcitx5 -r, or
603  * Instance::restart will just be no-op.
604  *
605  * @return whether it is safe for fcitx to restart on its own.
606  * @see AddonInstance::setCanRestart
607  * @since 5.1.6
608  */
609  bool canRestart() const;
610 
611 protected:
612  // For testing purpose
613  InstancePrivate *privateData();
614 
615 private:
616  void handleSignal();
617 
618  bool canTrigger() const;
619  bool canAltTrigger(InputContext *ic) const;
620  bool canEnumerate(InputContext *ic) const;
621  bool canChangeGroup() const;
622  bool trigger(InputContext *ic, bool totallyReleased);
623  bool altTrigger(InputContext *ic);
624  bool activate(InputContext *ic);
625  bool deactivate(InputContext *ic);
626  bool enumerate(InputContext *ic, bool forward);
627  bool toggle(InputContext *ic, InputMethodSwitchedReason reason =
629 
630  void activateInputMethod(InputContextEvent &event);
631  void deactivateInputMethod(InputContextEvent &event);
632 
633  std::unique_ptr<InstancePrivate> d_ptr;
634  FCITX_DECLARE_PRIVATE(Instance);
635 };
636 }; // namespace fcitx
637 
638 #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