Fcitx
tempmodemanager.cpp
1 /*
2  * SPDX-FileCopyrightText: 2026-2026 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 
8 #include "tempmodemanager.h"
9 #include <memory>
10 #include "fcitx-utils/handlertable.h"
11 #include "fcitx-utils/macros.h"
12 #include "event.h"
13 #include "instance.h"
14 #include "tempmode.h"
15 #include "tempmode_p.h"
16 
17 namespace fcitx {
18 
20 public:
21  explicit TempModeManagerPrivate(Instance *instance) : instance_(instance) {
22  postInputMethodHandler_ =
24  EventWatcherPhase::Default,
25  [this](KeyEvent &event) { checkModeTrigger(event); });
26 
27  preInputMethodHandler_ =
29  EventWatcherPhase::PreInputMethod,
30  [this](KeyEvent &event) { keyEvent(event); });
31 
32  invokeActionHandler_ =
34  EventWatcherPhase::PreInputMethod,
35  [this](InvokeActionEvent &event) { invokeAction(event); });
36 
37  auto reset = [this](const auto &event) {
38  for (auto *mode : modes_.view()) {
39  if (mode->isActive(event.inputContext())) {
40  mode->reset(event.inputContext());
41  }
42  }
43  };
44  focusOutHandler_ =
46  EventWatcherPhase::Default, reset);
47  resetHandler_ = instance->watchEvent<EventType::InputContextReset>(
48  EventWatcherPhase::Default, reset);
49  switchInputMethodHandler_ =
51  EventWatcherPhase::Default, reset);
52  }
53 
54  void checkModeTrigger(KeyEvent &keyEvent) const {
55  for (auto *mode : modes_.view()) {
56  if (mode->triggerTempMode(keyEvent)) {
57  keyEvent.filterAndAccept();
58  return;
59  }
60  }
61  }
62 
63  void keyEvent(KeyEvent &keyEvent) const {
64  for (auto *mode : modes_.view()) {
65  if (mode->isActive(keyEvent.inputContext())) {
66  keyEvent.filter();
67  if (mode->keyEvent(keyEvent)) {
68  keyEvent.accept();
69  }
70  return;
71  }
72  }
73  }
74 
75  void invokeAction(InvokeActionEvent &event) const {
76  for (auto *mode : modes_.view()) {
77  if (mode->isActive(event.inputContext())) {
78  event.filter();
79  if (mode->invokeAction(event)) {
80  event.accept();
81  }
82  return;
83  }
84  }
85  }
86 
87  Instance *instance_;
88  std::unique_ptr<HandlerTableEntry<EventHandler>> postInputMethodHandler_;
89  std::unique_ptr<HandlerTableEntry<EventHandler>> preInputMethodHandler_;
90  std::unique_ptr<HandlerTableEntry<EventHandler>> invokeActionHandler_;
91  std::unique_ptr<HandlerTableEntry<EventHandler>> focusOutHandler_;
92  std::unique_ptr<HandlerTableEntry<EventHandler>> resetHandler_;
93  std::unique_ptr<HandlerTableEntry<EventHandler>> switchInputMethodHandler_;
95 };
96 
98  : d_ptr(std::make_unique<TempModeManagerPrivate>(instance)) {}
99 
100 TempModeManager::~TempModeManager() {
101  FCITX_D();
102  for (auto *mode : d->modes_.view()) {
103  mode->unregister();
104  }
105 }
106 
108  FCITX_D();
109  if (tempMode.isRegistered()) {
110  return;
111  }
112  tempMode.d_ptr->registerCallback(d->modes_.add(&tempMode), d->instance_);
113 }
114 
115 } // namespace fcitx
bool isRegistered() const
Return whether this temp mode is registered with a manager.
Definition: tempmode.cpp:21
Temporary input modes for Fcitx.
ResetEvent is generated.
An instance represents a standalone Fcitx instance.
Definition: instance.h:92
when user switch to a different input method by hand such as ctrl+shift by default, or by ui, default behavior is reset IM.
Definition: action.cpp:17
Definition: matchrule.h:78
TempModeManager(Instance *instance)
Create a temp mode manager for an instance.
A temporary mode that can take over key handling for a short period.
Definition: tempmode.h:45
FCITX_NODISCARD std::unique_ptr< HandlerTableEntry< EventHandler > > watchEvent(EventType type, EventWatcherPhase phase, EventHandler callback)
Add a callback to for certain event type.
Definition: instance.cpp:1714
InvokeAction event is generated when client click on the preedit.
void registerTempMode(TempMode &tempMode)
Register a temp mode with this manager.
Key event is generated when client press or release a key.
Registration and dispatch for temporary input modes.
when using lost focus this might be variance case to case.