Fcitx
event.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 #ifndef _FCITX_EVENT_H_
8 #define _FCITX_EVENT_H_
9 
10 #include <cstdint>
12 #include <fcitx-utils/key.h>
13 #include <fcitx/userinterface.h>
14 #include "fcitxcore_export.h"
15 
16 /// \addtogroup FcitxCore
17 /// \{
18 /// \file
19 /// \brief Input Method event for Fcitx.
20 
21 namespace fcitx {
22 
23 class InputContext;
24 class FocusGroup;
25 
26 enum class ResetReason {
27  ChangeByInactivate FCITXCORE_DEPRECATED,
28  LostFocus FCITXCORE_DEPRECATED,
29  SwitchIM FCITXCORE_DEPRECATED,
30  Client
31 };
32 
33 /**
34  * The reason why input method is switched to another.
35  */
37  /// Switched by trigger key
38  Trigger,
39  /// Switched by deactivate key
40  Deactivate,
41  /// Switched by alternative trigger key
42  AltTrigger,
43  /// Switched by activate key
44  Activate,
45  /// Switched by enumerate key
46  Enumerate,
47  /// Switched by group change
49  /// Switched by capability change (e.g. password field)
51  /// miscellaneous reason
52  Other,
53 };
54 
55 enum class InputMethodMode { PhysicalKeyboard, OnScreenKeyboard };
56 
57 /**
58  * Type of input method events.
59  */
60 enum class EventType : uint32_t {
61  EventTypeFlag = 0xfffff000,
62  UserTypeFlag = 0xffff0000,
63  // send by frontend, captured by core, input method, or module
64  InputContextEventFlag = 0x0001000,
65  // send by im, captured by frontend, or module
66  InputMethodEventFlag = 0x0002000,
67 
68  /**
69  * captured by everything
70  */
71  InstanceEventFlag = 0x0003000,
72  InputContextCreated = InputContextEventFlag | 0x1,
73  InputContextDestroyed = InputContextEventFlag | 0x2,
74  /**
75  * FocusInEvent is generated when client gets focused.
76  *
77  * @see FocusInEvent
78  */
79  InputContextFocusIn = InputContextEventFlag | 0x3,
80  /**
81  * when using lost focus
82  * this might be variance case to case. the default behavior is to commit
83  * the preedit, and resetIM.
84  *
85  * Controlled by [Output/DontCommitPreeditWhenUnfocus], this option will not
86  * work for application switch doesn't support async commit.
87  *
88  * So OnClose is called when preedit IS committed (not like
89  * CChangeByInactivate,
90  * this behavior cannot be overridden), it give im a chance to choose
91  * remember this
92  * word or not.
93  *
94  * Input method need to notice, that the commit is already DONE, do not do
95  * extra commit.
96  *
97  * @see FocusOutEvent
98  */
99  InputContextFocusOut = InputContextEventFlag | 0x4,
100  /**
101  * Key event is generated when client press or release a key.
102  * @see KeyEvent
103  */
104  InputContextKeyEvent = InputContextEventFlag | 0x5,
105  /**
106  * ResetEvent is generated
107  *
108  */
109  InputContextReset = InputContextEventFlag | 0x6,
110  InputContextSurroundingTextUpdated = InputContextEventFlag | 0x7,
111  InputContextCapabilityChanged = InputContextEventFlag | 0x8,
112  InputContextCursorRectChanged = InputContextEventFlag | 0x9,
113  InputContextCapabilityAboutToChange = InputContextEventFlag | 0xD,
114  /**
115  * when user switch to a different input method by hand
116  * such as ctrl+shift by default, or by ui,
117  * default behavior is reset IM.
118  */
119  InputContextSwitchInputMethod = InputContextEventFlag | 0xA,
120 
121  // Two convenient event after input method is actually activate and
122  // deactivated. Useful for UI to update after specific input method get
123  // activated and deactivated. Will not be emitted if the input method is not
124  // a valid one.
125  InputContextInputMethodActivated = InputContextEventFlag | 0xB,
126  InputContextInputMethodDeactivated = InputContextEventFlag | 0xC,
127  /**
128  * InvokeAction event is generated when client click on the preedit.
129  *
130  * Not all client support this feature.
131  *
132  * @since 5.0.11
133  */
134  InputContextInvokeAction = InputContextEventFlag | 0xE,
135 
136  InputContextVirtualKeyboardEvent = InputContextEventFlag | 0xF,
137 
138  InputContextForwardKey = InputMethodEventFlag | 0x1,
139  InputContextCommitString = InputMethodEventFlag | 0x2,
140  InputContextDeleteSurroundingText = InputMethodEventFlag | 0x3,
141  InputContextUpdatePreedit = InputMethodEventFlag | 0x4,
142  InputContextUpdateUI = InputMethodEventFlag | 0x5,
143  InputContextCommitStringWithCursor = InputMethodEventFlag | 0x6,
144  InputContextFlushUI = InputMethodEventFlag | 0x7,
145 
146  /**
147  * This is generated when input method group changed.
148  * This would also trigger InputContextSwitchInputMethod afterwards.
149  */
151  /**
152  * InputMethodGroupAboutToChangeEvent is generated when input method group
153  * is about to be changed.
154  *
155  * @see InputMethodGroupAboutToChange
156  */
158  /**
159  * UIChangedEvent is posted when the UI implementation is changed.
160  */
162  /**
163  * CheckUpdateEvent is posted when the Instance is requested to check for
164  * newly installed addons and input methods.
165  *
166  * This can be used for addons to pick up new input methods if it provides
167  * input method at runtime.
168  */
170  /**
171  * FocusGroupFocusChanged is posted when a focus group changed its focused
172  * input context.
173  *
174  * This is a more fine grained control over focus in and focus out event.
175  * This is more useful for UI to keep track of what input context is being
176  * focused.
177  *
178  * @see FocusInEvent
179  * @see FocusOutEvent
180  */
182  /**
183  * Input method mode changed
184  */
186  /**
187  * Global config is reloaded
188  *
189  * This only fires after fcitx has entered running state.
190  * The initial load will not trigger this event.
191  * @see GlobalConfig
192  * @since 5.1.0
193  */
195  /**
196  * Virtual keyboard visibility changed
197  *
198  * @see UserInterfaceManager
199  * @since 5.1.0
200  */
202 };
203 
204 /**
205  * Base class for fcitx event.
206  */
207 class FCITXCORE_EXPORT Event {
208 public:
209  Event(EventType type) : type_(type) {}
210  virtual ~Event();
211 
212  /**
213  * Type of event, can be used to decide event class.
214  *
215  * @return fcitx::EventType
216  */
217  EventType type() const { return type_; }
218 
219  void accept() { accepted_ = true; }
220  /**
221  * Return value used by Instance::postEvent.
222  *
223  * @see Instance::postEvent
224  * @return bool
225  */
226  bool accepted() const { return accepted_; }
227 
228  /**
229  * Whether a event is filtered by handler.
230  *
231  * If event is filtered, it will not send to another handler.
232  * For now only keyevent from input context can be filtered.
233  *
234  * @return bool
235  */
236  virtual bool filtered() const { return false; }
237 
238  /**
239  * A helper function to check if a event is input context event.
240  *
241  * @return bool
242  */
243  bool isInputContextEvent() const {
244  auto flag = static_cast<uint32_t>(EventType::InputContextEventFlag);
245  auto mask = static_cast<uint32_t>(EventType::EventTypeFlag);
246  return (static_cast<uint32_t>(type_) & mask) == flag;
247  }
248 
249 protected:
250  EventType type_;
251  bool accepted_ = false;
252 };
253 
254 class FCITXCORE_EXPORT InputContextEvent : public Event {
255 public:
257  : Event(type), ic_(context) {}
258 
259  InputContext *inputContext() const { return ic_; }
260 
261 protected:
262  InputContext *ic_;
263 };
264 
265 class FCITXCORE_EXPORT KeyEventBase : public InputContextEvent {
266 public:
267  KeyEventBase(EventType type, InputContext *context, Key rawKey,
268  bool isRelease = false, int time = 0);
269  KeyEventBase(const KeyEventBase &) = default;
270 
271  /**
272  * Normalized key event.
273  *
274  * @return fcitx::Key
275  */
276  Key key() const { return key_; }
277 
278  /**
279  * It will automatically be called if input method layout does not match the
280  * system keyboard layout.
281  *
282  * @param key p_key:...
283  */
284  void setKey(const Key &key) {
285  key_ = key;
286  forward_ = true;
287  }
288 
289  /**
290  * It is designed for faking the key event. Normally should not be used.
291  *
292  * @param key key event to override.
293  * @since 5.0.4
294  */
295  void setRawKey(const Key &key) {
296  rawKey_ = key;
297  key_ = key.normalize();
298  forward_ = true;
299  }
300 
301  /**
302  * It is designed for overriding the key forward option. Normally should not
303  * be used.
304  *
305  * @param forward
306  * @since 5.0.4
307  */
308  void setForward(bool forward) { forward_ = forward; }
309 
310  /**
311  * Key event regardless of keyboard layout conversion.
312  *
313  * @return fcitx::Key
314  */
315  Key origKey() const { return origKey_; }
316 
317  /**
318  * Key event after layout conversion.
319  *
320  * Basically it is the "unnormalized" key event.
321  *
322  * @return fcitx::Key
323  */
324  Key rawKey() const { return rawKey_; }
325  bool isRelease() const { return isRelease_; }
326  int time() const { return time_; }
327 
328  /**
329  * If true, the key that produce character will commit a string.
330  *
331  * This is currently used by internal keyboard layout translation.
332  *
333  * @return bool
334  */
335  bool forward() const { return forward_; }
336 
337  /**
338  * Whether this key event is derived from a virtual keyboard
339  *
340  * @return bool
341  * @since 5.1.2
342  */
343  bool isVirtual() const { return origKey_.isVirtual(); }
344 
345 protected:
346  Key key_, origKey_, rawKey_;
347  bool isRelease_;
348  int time_;
349  bool forward_ = false;
350 };
351 
352 class FCITXCORE_EXPORT KeyEvent : public KeyEventBase {
353 public:
354  KeyEvent(InputContext *context, Key rawKey, bool isRelease = false,
355  int time = 0)
357  isRelease, time) {}
358 
359  void filter() { filtered_ = true; }
360  bool filtered() const override { return filtered_; }
361  void filterAndAccept() {
362  filter();
363  accept();
364  }
365 
366 private:
367  bool filtered_ = false;
368 };
369 
371 
372 class FCITXCORE_EXPORT VirtualKeyboardEvent : public InputContextEvent {
373 public:
374  VirtualKeyboardEvent(InputContext *context, bool isRelease, int time = 0);
376 
377  int time() const;
378 
379  void setKey(Key key);
380  const Key &key() const;
381 
382  void setPosition(float x, float y);
383  float x() const;
384  float y() const;
385 
386  void setLongPress(bool longPress);
387  bool isLongPress() const;
388 
389  void setUserAction(uint64_t actionId);
390  uint64_t userAction() const;
391 
392  void setText(std::string text);
393  const std::string &text() const;
394 
395  std::unique_ptr<KeyEvent> toKeyEvent() const;
396 
397 protected:
398  FCITX_DECLARE_PRIVATE(VirtualKeyboardEvent);
399  std::unique_ptr<VirtualKeyboardEventPrivate> d_ptr;
400 };
401 
402 class FCITXCORE_EXPORT ForwardKeyEvent : public KeyEventBase {
403 public:
404  ForwardKeyEvent(InputContext *context, Key rawKey, bool isRelease = false,
405  int time = 0)
406  : KeyEventBase(EventType::InputContextForwardKey, context, rawKey,
407  isRelease, time) {}
408 };
409 
410 class FCITXCORE_EXPORT CommitStringEvent : public InputContextEvent {
411 public:
412  CommitStringEvent(const std::string &text, InputContext *context)
413  : InputContextEvent(context, EventType::InputContextCommitString),
414  text_(text) {}
415 
416  const std::string &text() const { return text_; }
417 
418 protected:
419  std::string text_;
420 };
421 
422 /**
423  * Event for commit string with cursor
424  *
425  * @see InputContext::commitStringWithCursor
426  * @since 5.1.2
427  */
428 class FCITXCORE_EXPORT CommitStringWithCursorEvent : public InputContextEvent {
429 public:
430  CommitStringWithCursorEvent(std::string text, size_t cursor,
431  InputContext *context)
432  : InputContextEvent(context,
433  EventType::InputContextCommitStringWithCursor),
434  text_(std::move(text)), cursor_(cursor) {}
435 
436  const std::string &text() const { return text_; }
437  size_t cursor() const { return cursor_; }
438 
439 protected:
440  std::string text_;
441  size_t cursor_;
442 };
443 
444 class FCITXCORE_EXPORT InvokeActionEvent : public InputContextEvent {
445 public:
446  enum class Action { LeftClick, RightClick };
447  InvokeActionEvent(Action action, int cursor, InputContext *context)
449  action_(action), cursor_(cursor) {}
450 
451  Action action() const { return action_; }
452  int cursor() const { return cursor_; }
453 
454  void filter() {
455  filtered_ = true;
456  accept();
457  }
458  bool filtered() const override { return filtered_; }
459 
460 protected:
461  Action action_;
462  int cursor_;
463  bool filtered_ = false;
464 };
465 
467  : public InputContextEvent {
468 public:
470  const std::string &oldIM,
471  InputContext *context)
473  reason_(reason), oldInputMethod_(oldIM) {}
474 
475  InputMethodSwitchedReason reason() const { return reason_; }
476  const std::string &oldInputMethod() const { return oldInputMethod_; }
477 
478 protected:
480  std::string oldInputMethod_;
481 };
482 
483 class FCITXCORE_EXPORT ResetEvent : public InputContextEvent {
484 public:
485  FCITXCORE_DEPRECATED ResetEvent(ResetReason reason, InputContext *context)
487  reason_(reason) {}
488  ResetEvent(InputContext *context)
490  reason_(ResetReason::Client) {}
491 
492  FCITXCORE_DEPRECATED ResetReason reason() const { return reason_; }
493 
494 protected:
495  ResetReason reason_;
496 };
497 
498 class FCITXCORE_EXPORT InputContextUpdateUIEvent : public InputContextEvent {
499 public:
501  InputContext *context, bool immediate = false)
502  : InputContextEvent(context, EventType::InputContextUpdateUI),
503  component_(component), immediate_(immediate) {}
504 
505  UserInterfaceComponent component() const { return component_; }
506  bool immediate() const { return immediate_; }
507 
508 protected:
509  UserInterfaceComponent component_;
510  bool immediate_;
511 };
512 
513 /**
514  * Events triggered that user interface manager that flush the UI update.
515  *
516  * @since 5.1.2
517  */
518 class FCITXCORE_EXPORT InputContextFlushUIEvent : public InputContextEvent {
519 public:
521  InputContext *context)
522  : InputContextEvent(context, EventType::InputContextFlushUI),
523  component_(component) {}
524 
525  UserInterfaceComponent component() const { return component_; }
526 
527 protected:
528  UserInterfaceComponent component_;
529 };
530 
531 class FCITXCORE_EXPORT VirtualKeyboardVisibilityChangedEvent : public Event {
532 public:
535 };
536 
537 class FCITXCORE_EXPORT InputMethodNotificationEvent : public InputContextEvent {
538 public:
539  InputMethodNotificationEvent(EventType type, const std::string &name,
540  InputContext *context)
541  : InputContextEvent(context, type), name_(name) {}
542 
543  const std::string &name() const { return name_; }
544 
545 protected:
546  std::string name_;
547 };
548 
549 class FCITXCORE_EXPORT InputMethodActivatedEvent
551 public:
552  InputMethodActivatedEvent(const std::string &name, InputContext *context)
554  EventType::InputContextInputMethodActivated, name, context) {}
555 };
556 
557 class FCITXCORE_EXPORT InputMethodDeactivatedEvent
559 public:
560  InputMethodDeactivatedEvent(const std::string &name, InputContext *context)
562  EventType::InputContextInputMethodDeactivated, name, context) {}
563 };
564 
565 #define FCITX_DEFINE_SIMPLE_EVENT(NAME, TYPE, ARGS...) \
566  struct FCITXCORE_EXPORT NAME##Event : public InputContextEvent { \
567  NAME##Event(InputContext *ic) \
568  : InputContextEvent(ic, EventType::TYPE) {} \
569  }
570 
571 FCITX_DEFINE_SIMPLE_EVENT(InputContextCreated, InputContextCreated);
572 FCITX_DEFINE_SIMPLE_EVENT(InputContextDestroyed, InputContextDestroyed);
573 FCITX_DEFINE_SIMPLE_EVENT(FocusIn, InputContextFocusIn);
574 FCITX_DEFINE_SIMPLE_EVENT(FocusOut, InputContextFocusOut);
575 FCITX_DEFINE_SIMPLE_EVENT(SurroundingTextUpdated,
576  InputContextSurroundingTextUpdated);
577 FCITX_DEFINE_SIMPLE_EVENT(CursorRectChanged, InputContextCursorRectChanged);
578 FCITX_DEFINE_SIMPLE_EVENT(UpdatePreedit, InputContextUpdatePreedit);
579 
580 class FCITXCORE_EXPORT InputMethodGroupChangedEvent : public Event {
581 public:
584 };
585 
586 class FCITXCORE_EXPORT InputMethodGroupAboutToChangeEvent : public Event {
587 public:
590 };
591 
592 class FCITXCORE_EXPORT UIChangedEvent : public Event {
593 public:
595 };
596 
597 class FCITXCORE_EXPORT CheckUpdateEvent : public Event {
598 public:
600 
601  /// Make checking update short circuit. If anything need a refresh, just
602  /// simply break.
603  void setHasUpdate() {
604  filtered_ = true;
605  accept();
606  }
607  bool filtered() const override { return filtered_; }
608 
609 private:
610  bool filtered_ = false;
611 };
612 
613 /**
614  * Notify a focus change for focus group.
615  *
616  * @since 5.0.11
617  */
618 class FCITXCORE_EXPORT FocusGroupFocusChangedEvent : public Event {
619 public:
621  InputContext *newFocus)
622  : Event(EventType::FocusGroupFocusChanged), group_(group),
623  oldFocus_(oldFocus), newFocus_(newFocus) {}
624 
625  FocusGroup *group() const { return group_; }
626  InputContext *oldFocus() const { return oldFocus_; };
627  InputContext *newFocus() const { return newFocus_; };
628 
629 private:
630  FocusGroup *group_;
631  InputContext *oldFocus_;
632  InputContext *newFocus_;
633 };
634 
635 /**
636  * Notify the input method mode is changed.
637  *
638  * @see Instance::InputMethodMode
639  * @since 5.1.0
640  */
641 class FCITXCORE_EXPORT InputMethodModeChangedEvent : public Event {
642 public:
644 };
645 
646 /**
647  * Notify the global config is reloaded.
648  *
649  * @see GlobalConfig
650  * @since 5.1.0
651  */
652 class FCITXCORE_EXPORT GlobalConfigReloadedEvent : public Event {
653 public:
655 };
656 
657 class FCITXCORE_EXPORT CapabilityEvent : public InputContextEvent {
658 public:
660  CapabilityFlags newFlags)
661  : InputContextEvent(ic, type), oldFlags_(oldFlags),
662  newFlags_(newFlags) {}
663 
664  auto oldFlags() const { return oldFlags_; }
665  auto newFlags() const { return newFlags_; }
666 
667 protected:
668  const CapabilityFlags oldFlags_;
669  const CapabilityFlags newFlags_;
670 };
671 
672 class FCITXCORE_EXPORT CapabilityChangedEvent : public CapabilityEvent {
673 public:
675  CapabilityFlags newFlags)
676  : CapabilityEvent(ic, EventType::InputContextCapabilityChanged,
677  oldFlags, newFlags) {}
678 };
679 
680 class FCITXCORE_EXPORT CapabilityAboutToChangeEvent : public CapabilityEvent {
681 public:
683  CapabilityFlags newFlags)
684  : CapabilityEvent(ic, EventType::InputContextCapabilityAboutToChange,
685  oldFlags, newFlags) {}
686 };
687 
688 } // namespace fcitx
689 
690 #endif // _FCITX_EVENT_H_
InputMethodGroupAboutToChangeEvent is generated when input method group is about to be changed...
Describe a Key in fcitx.
Definition: key.h:40
bool accepted() const
Return value used by Instance::postEvent.
Definition: event.h:226
EventType
Type of input method events.
Definition: event.h:60
Switched by alternative trigger key.
void setHasUpdate()
Make checking update short circuit.
Definition: event.h:603
ResetEvent is generated.
FocusInEvent is generated when client gets focused.
Notify a focus change for focus group.
Definition: event.h:618
This is generated when input method group changed.
when user switch to a different input method by hand such as ctrl+shift by default, or by ui, default behavior is reset IM.
InputMethodSwitchedReason
The reason why input method is switched to another.
Definition: event.h:36
Definition: action.cpp:12
void setKey(const Key &key)
It will automatically be called if input method layout does not match the system keyboard layout...
Definition: event.h:284
Key key() const
Normalized key event.
Definition: event.h:276
bool isVirtual() const
Whether this key event is derived from a virtual keyboard.
Definition: event.h:343
virtual bool filtered() const
Whether a event is filtered by handler.
Definition: event.h:236
bool filtered() const override
Whether a event is filtered by handler.
Definition: event.h:360
Base class for fcitx event.
Definition: event.h:207
Virtual keyboard visibility changed.
Enum type for input context capability.
Switched by capability change (e.g. password field)
Base class for User Interface addon.
Global config is reloaded.
Events triggered that user interface manager that flush the UI update.
Definition: event.h:518
InvokeAction event is generated when client click on the preedit.
bool filtered() const override
Whether a event is filtered by handler.
Definition: event.h:607
FocusGroupFocusChanged is posted when a focus group changed its focused input context.
UserInterfaceComponent
Definition: userinterface.h:21
Key rawKey() const
Key event after layout conversion.
Definition: event.h:324
Notify the input method mode is changed.
Definition: event.h:641
CheckUpdateEvent is posted when the Instance is requested to check for newly installed addons and inp...
Input method mode changed.
bool filtered() const override
Whether a event is filtered by handler.
Definition: event.h:458
bool isInputContextEvent() const
A helper function to check if a event is input context event.
Definition: event.h:243
UIChangedEvent is posted when the UI implementation is changed.
Key origKey() const
Key event regardless of keyboard layout conversion.
Definition: event.h:315
Class provides bit flag support for Enum.
Definition: flags.h:33
Event for commit string with cursor.
Definition: event.h:428
EventType type() const
Type of event, can be used to decide event class.
Definition: event.h:217
An input context represents a client of Fcitx.
Definition: inputcontext.h:45
Key event is generated when client press or release a key.
Class to represent a key.
void setRawKey(const Key &key)
It is designed for faking the key event.
Definition: event.h:295
bool forward() const
If true, the key that produce character will commit a string.
Definition: event.h:335
void setForward(bool forward)
It is designed for overriding the key forward option.
Definition: event.h:308
Notify the global config is reloaded.
Definition: event.h:652
when using lost focus this might be variance case to case.
Key normalize() const
Normalize a key, usually used when key is from frontend.
Definition: key.cpp:471