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 <memory> 11 #include <fcitx-utils/connectableobject.h> 12 #include <fcitx-utils/handlertable.h> 13 #include <fcitx-utils/macros.h> 14 #include <fcitx/event.h> 15 #include <fcitx/globalconfig.h> 16 #include <fcitx/text.h> 17 #include "fcitxcore_export.h" 18 19 #define FCITX_INVALID_COMPOSE_RESULT 0xffffffff 20 21 namespace fcitx { 22 23 class InputContext; 24 class KeyEvent; 25 class InstancePrivate; 26 class EventLoop; 27 class AddonManager; 28 class InputContextManager; 29 class InputMethodManager; 30 class InputMethodEngine; 31 class InputMethodEntry; 32 class UserInterfaceManager; 33 class GlobalConfig; 34 class FocusGroup; 35 36 typedef std::function<void(Event &event)> EventHandler; 37 38 /** 39 * The event handling phase of event pipeline. 40 */ 41 enum class EventWatcherPhase { 42 /** 43 * Handler executed before input method. 44 * 45 * Useful for addons that want to implement an independent mode. 46 * 47 * A common workflow of such addon is: 48 * 1. Check a hotkey in PostInputMethod phase to trigger the mode 49 * 2. Handle all the key event in PreInputMethod phase just like regular 50 * input method. 51 */ 52 PreInputMethod, 53 /** 54 * Handlers to be executed right after input method. 55 * 56 * The input method keyEvent is registered with an internal handler. So all 57 * the new handler in this phase will still executed after input method. 58 */ 59 InputMethod, 60 /** 61 * Handlers to be executed after input method. 62 * 63 * common use case is when you want to implement a key that triggers a 64 * standalone action. 65 */ 66 PostInputMethod, 67 /// Internal phase to be executed first 68 ReservedFirst, 69 /// Internal phase to be executed last 70 ReservedLast, 71 Default = PostInputMethod 72 }; 73 74 struct FCITXCORE_EXPORT InstanceQuietQuit : public std::exception {}; 75 76 /** 77 * An instance represents a standalone Fcitx instance. Usually there is only one 78 * of such object. 79 * 80 * Fcitx Instance provides the access to all the addons and sub components. It 81 * also provides a event pipeline for handling input method related event. 82 */ 83 class FCITXCORE_EXPORT Instance : public ConnectableObject { 84 public: 85 /** 86 * A main function like construct to be used to create Fcitx Instance. 87 * 88 * For more details, see --help of fcitx5 command. 89 * 90 * @param argc number of argument 91 * @param argv command line arguments 92 */ 93 Instance(int argc, char *argv[]); 94 95 ~Instance(); 96 initialized()97 bool initialized() const { return !!d_ptr; } 98 99 /** 100 * Set the pipe forwarding unix signal information. 101 * 102 * Fcitx Instance is running within its own thread, usually main thread. In 103 * order to make it handle signal correctly in a thread-safe way, it is 104 * possible to set a file descriptor that write the signal number received 105 * by the signal handler. Usually this is done through a self-pipe. This is 106 * already handled by Fcitx default server implementation, normal addon user 107 * should not touch this. The common usecase is when you want to embed Fcitx 108 * into your own program. 109 * 110 * @param fd file descriptor 111 */ 112 void setSignalPipe(int fd); 113 114 /** 115 * Start the event loop of Fcitx. 116 * 117 * @return return value that can be used as main function return code. 118 */ 119 int exec(); 120 121 /** 122 * Check whether command line specify if it will replace an existing fcitx 123 * server. 124 * 125 * This function is only useful if your addon provides a way to replace 126 * existing fcitx server. Basically it is checking whether -r is passed to 127 * fcitx command line. 128 * 129 * @return whether to replace existing fcitx server. Default value is false. 130 */ 131 bool willTryReplace() const; 132 133 /** 134 * Check whether command line specify whether to keep fcitx running. 135 * 136 * There could be multiple display server, such as X/Wayland/etc. Fcitx 137 * usually will exit when the connection is closed. Command line -k can 138 * override this behavior and keep Fcitx running. 139 * 140 * @return whether to exit after main display is disconnected. 141 */ 142 bool exitWhenMainDisplayDisconnected() const; 143 144 /** 145 * Check whether fcitx is in exiting process. 146 * 147 * @return 148 */ 149 bool exiting() const; 150 151 /// Get the fcitx event loop. 152 EventLoop &eventLoop(); 153 154 /// Get the addon manager. 155 AddonManager &addonManager(); 156 157 /// Get the input context manager 158 InputContextManager &inputContextManager(); 159 160 /// Get the user interface manager 161 UserInterfaceManager &userInterfaceManager(); 162 163 /// Get the input method manager 164 InputMethodManager &inputMethodManager(); 165 166 /// Get the input method manager 167 const InputMethodManager &inputMethodManager() const; 168 169 /// Get the global config. 170 GlobalConfig &globalConfig(); 171 172 // TODO: Merge this when we can break API. 173 bool postEvent(Event &event); postEvent(Event && event)174 bool postEvent(Event &&event) { return postEvent(event); } 175 176 /** 177 * Put a event to the event pipe line. 178 * 179 * @param event Input method event 180 * @return return the value of event.accepted() 181 */ 182 bool postEvent(Event &event) const; postEvent(Event && event)183 bool postEvent(Event &&event) const { return postEvent(event); } 184 185 /** 186 * Add a callback to for certain event type. 187 * 188 * @param type event type 189 * @param phase the stage that callback will be executed. 190 * @param callback callback function. 191 * @return Handle to the callback, the callback will be removed when it is 192 * deleted. 193 */ 194 FCITX_NODISCARD std::unique_ptr<HandlerTableEntry<EventHandler>> 195 watchEvent(EventType type, EventWatcherPhase phase, EventHandler callback); 196 197 /// Return the unique name of input method for given input context. 198 std::string inputMethod(InputContext *ic); 199 200 /// Return the input method entry for given input context. 201 const InputMethodEntry *inputMethodEntry(InputContext *ic); 202 203 /// Return the input method engine object for given input context. 204 InputMethodEngine *inputMethodEngine(InputContext *ic); 205 206 /// Return the input method engine object for given unique input method 207 /// name. 208 InputMethodEngine *inputMethodEngine(const std::string &name); 209 210 /** 211 * Return the input method icon for input context. 212 * 213 * It will fallback to input-keyboard by default if no input method is 214 * available. 215 * 216 * @param ic input context 217 * @return icon name. 218 * 219 * @see InputMethodEngine::subModeIcon 220 */ 221 std::string inputMethodIcon(InputContext *ic); 222 223 /** 224 * Return the input method label for input context. 225 * 226 * @param ic input context 227 * @return label. 228 * 229 * @see InputMethodEngine::subModeLabel 230 * @since 5.0.11 231 */ 232 std::string inputMethodLabel(InputContext *ic); 233 234 /** 235 * Handle current XCompose state. 236 * 237 * @param ic input context. 238 * @param keysym key symbol. 239 * 240 * @return unicode 241 * 242 * @see processComposeString 243 */ 244 FCITXCORE_DEPRECATED uint32_t processCompose(InputContext *ic, 245 KeySym keysym); 246 247 /** 248 * Handle current XCompose state. 249 * 250 * @param ic input context. 251 * @param keysym key symbol. 252 * 253 * @return the composed string, if it returns nullopt, it means compose is 254 * invalid. 255 * 256 * @see processComposeString 257 * @since 5.0.4 258 */ 259 std::optional<std::string> processComposeString(InputContext *ic, 260 KeySym keysym); 261 262 /// Reset the compose state. 263 void resetCompose(InputContext *inputContext); 264 265 /** 266 * Update the commit string to frontend 267 * 268 * This function should be not be used directly since it is already used 269 * internally by InputContext::commitString. 270 * 271 * @param inputContext input context 272 * @param orig original string 273 * @return the updated string. 274 * @see InputContext::commitString 275 */ 276 std::string commitFilter(InputContext *inputContext, 277 const std::string &orig); 278 /** 279 * Update the string that will be displayed in user interface. 280 * 281 * This function should only be used by frontend for client preedit, or user 282 * interface, for the other field in input panel. 283 * 284 * @see InputPanel 285 * 286 * @param inputContext input context 287 * @param orig orig text 288 * @return fcitx::Text 289 */ 290 Text outputFilter(InputContext *inputContext, const Text &orig); 291 292 FCITX_DECLARE_SIGNAL(Instance, CommitFilter, 293 void(InputContext *inputContext, std::string &orig)); 294 FCITX_DECLARE_SIGNAL(Instance, OutputFilter, 295 void(InputContext *inputContext, Text &orig)); 296 FCITX_DECLARE_SIGNAL(Instance, KeyEventResult, 297 void(const KeyEvent &keyEvent)); 298 /** 299 * \deprecated 300 */ 301 FCITX_DECLARE_SIGNAL(Instance, CheckUpdate, bool()); 302 303 /// Return a focused input context. 304 InputContext *lastFocusedInputContext(); 305 /// Return the most recent focused input context. If there isn't such ic, 306 /// return the last unfocused input context. 307 InputContext *mostRecentInputContext(); 308 309 /// All user interface update is batched internally. This function will 310 /// flush all the batched UI update immediately. 311 void flushUI(); 312 313 // controller functions. 314 315 /// Exit the fcitx event loop 316 void exit(); 317 318 /// Restart fcitx instance, this should only be used within a regular Fcitx 319 /// server, not within embedded mode. 320 void restart(); 321 322 /// Launch configtool 323 void configure(); 324 325 FCITXCORE_DEPRECATED void configureAddon(const std::string &addon); 326 FCITXCORE_DEPRECATED void configureInputMethod(const std::string &imName); 327 328 /// Return the name of current user interface addon. 329 std::string currentUI(); 330 331 /// Return the addon name of given input method. 332 std::string addonForInputMethod(const std::string &imName); 333 334 // Following functions are operations against lastFocusedInputContext 335 336 /// Activate last focused input context. (Switch to the active input method) 337 void activate(); 338 339 /// Deactivate last focused input context. (Switch to the first input 340 /// method) 341 void deactivate(); 342 343 /// Toggle between the first input method and active input method. 344 void toggle(); 345 346 /// Reset the input method configuration and recreate based on system 347 /// language. 348 void resetInputMethodList(); 349 350 /// Return a fcitx5-remote compatible value for the state. 351 int state(); 352 353 /// Reload global config. 354 void reloadConfig(); 355 /// Reload certain addon config. 356 void reloadAddonConfig(const std::string &addonName); 357 /// Load newly installed input methods and addons. 358 void refresh(); 359 360 /// Return the current input method of last focused input context. 361 std::string currentInputMethod(); 362 363 /// Set the input method of last focused input context. 364 void setCurrentInputMethod(const std::string &imName); 365 366 /** 367 * Set the input method of given input context. 368 * 369 * The input method need to be within the current group. Local parameter can 370 * be used to set the input method only for this input context. 371 * 372 * @param ic input context 373 * @param imName unique name of a input method 374 * @param local 375 */ 376 void setCurrentInputMethod(InputContext *ic, const std::string &imName, 377 bool local); 378 379 /// Enumerate input method group 380 bool enumerateGroup(bool forward); 381 382 /// Enumerate input method with in current group 383 void enumerate(bool forward); 384 385 /** 386 * Get the default focus group with given display hint. 387 * 388 * This function is used by frontend to assign a focus group from an unknown 389 * display server. 390 * 391 * @param displayHint Display server hint, it can something like be x11: / 392 * wayland: 393 * @return focus group 394 */ 395 FocusGroup *defaultFocusGroup(const std::string &displayHint = {}); 396 397 /** 398 * Set xkb RLVMO tuple for given display 399 * 400 * @param display display name 401 * @param rule xkb rule name 402 * @param model xkb model name 403 * @param options xkb option 404 */ 405 void setXkbParameters(const std::string &display, const std::string &rule, 406 const std::string &model, const std::string &options); 407 408 /// Update xkb state mask for given display 409 void updateXkbStateMask(const std::string &display, uint32_t depressed_mods, 410 uint32_t latched_mods, uint32_t locked_mods); 411 412 /** 413 * Show a small popup with input popup window with current input method 414 * information. 415 * 416 * This is useful for input method that has multiple sub modes. It can be 417 * called with switching sub modes within the input method. 418 * 419 * @param ic input context. 420 */ 421 void showInputMethodInformation(InputContext *ic); 422 423 /** 424 * Check if need to invoke Instance::refresh. 425 * 426 * @return need update 427 * @see Instance::refresh 428 */ 429 bool checkUpdate() const; 430 431 /// Return the version string of Fcitx. 432 static const char *version(); 433 434 private: 435 void initialize(); 436 void handleSignal(); 437 void save(); 438 439 bool canTrigger() const; 440 bool canAltTrigger(InputContext *ic) const; 441 bool canEnumerate(InputContext *ic) const; 442 bool canChangeGroup() const; 443 bool trigger(InputContext *ic, bool totallyReleased); 444 bool altTrigger(InputContext *ic); 445 bool activate(InputContext *ic); 446 bool deactivate(InputContext *ic); 447 bool enumerate(InputContext *ic, bool forward); 448 bool toggle(InputContext *ic, InputMethodSwitchedReason reason = 449 InputMethodSwitchedReason::Trigger); 450 451 void activateInputMethod(InputContextEvent &event); 452 void deactivateInputMethod(InputContextEvent &event); 453 454 std::unique_ptr<InstancePrivate> d_ptr; 455 FCITX_DECLARE_PRIVATE(Instance); 456 }; 457 }; // namespace fcitx 458 459 #endif // _FCITX_INSTANCE_H_ 460