diff --git a/src/rimeaction.cpp b/src/rimeaction.cpp index 953cfc9..eb5f9d8 100644 --- a/src/rimeaction.cpp +++ b/src/rimeaction.cpp @@ -53,8 +53,6 @@ void ToggleAction::activate(InputContext *ic) { if (!state) { return; } - // Do not send notification since user is explicitly select it. - engine_->blockNotificationFor(30000); auto session = state->session(); Bool oldValue = api->get_option(session, option_.c_str()); api->set_option(session, option_.c_str(), !oldValue); diff --git a/src/rimeengine.cpp b/src/rimeengine.cpp index b335069..a21e302 100644 --- a/src/rimeengine.cpp +++ b/src/rimeengine.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,9 @@ namespace fcitx::rime { namespace { +// Allow notification for 60secs. +constexpr uint64_t NotificationTimeout = 60000000; + std::unordered_map> parseAppOptions(rime_api_t *api, RimeConfig *config) { std::unordered_map> @@ -210,7 +214,7 @@ RimeEngine::RimeEngine(Instance *instance) syncAction_.setShortText(_("Synchronize")); syncAction_.connect([this](InputContext *ic) { - sync(); + sync(/*userTriggered=*/true); auto *state = this->state(ic); if (state && ic->hasFocus()) { state->updateUI(ic, false); @@ -224,6 +228,8 @@ RimeEngine::RimeEngine(Instance *instance) globalConfigReloadHandle_ = instance_->watchEvent( EventType::GlobalConfigReloaded, EventWatcherPhase::Default, [this](Event &) { refreshSessionPoolPolicy(); }); + + allowNotification("failure"); reloadConfig(); constructed_ = true; } @@ -335,7 +341,7 @@ void RimeEngine::setSubConfig(const std::string &path, if (path == "deploy") { deploy(); } else if (path == "sync") { - sync(); + sync(/*userTriggered=*/true); } } @@ -504,7 +510,6 @@ void RimeEngine::deactivate(const InputMethodEntry &entry, void RimeEngine::keyEvent(const InputMethodEntry &entry, KeyEvent &event) { FCITX_UNUSED(entry); - lastKeyEventTime_ = now(CLOCK_MONOTONIC); RIME_DEBUG() << "Rime receive key: " << event.rawKey() << " " << event.isRelease(); auto *inputContext = event.inputContext(); @@ -513,7 +518,7 @@ void RimeEngine::keyEvent(const InputMethodEntry &entry, KeyEvent &event) { deploy(); return event.filterAndAccept(); } else if (event.key().checkKeyList(*config_.synchronize)) { - sync(); + sync(/*userTriggered=*/true); return event.filterAndAccept(); } } @@ -534,15 +539,12 @@ void RimeEngine::reset(const InputMethodEntry & /*entry*/, inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); } -void RimeEngine::blockNotificationFor(uint64_t usec) { - blockNotificationBefore_ = now(CLOCK_MONOTONIC) + usec; +void RimeEngine::allowNotification(std::string type) { + allowNotificationUntil_ = now(CLOCK_MONOTONIC) + NotificationTimeout; + allowNotificationType_ = std::move(type); } -void RimeEngine::save() { - // Block notification for 5 sec. - blockNotificationFor(5000000); - sync(); -} +void RimeEngine::save() { sync(/*userTriggered=*/false); } void RimeEngine::rimeNotificationHandler(void *context, RimeSessionId session, const char *messageType, @@ -578,7 +580,7 @@ void RimeEngine::notify(RimeSessionId session, const std::string &messageType, const char *message = nullptr; const char *icon = ""; const char *tipId = ""; - int timeout = 3000; + const int timeout = 3000; bool blockMessage = false; if (messageType == "deploy") { tipId = "fcitx-rime-deploy"; @@ -612,14 +614,17 @@ void RimeEngine::notify(RimeSessionId session, const std::string &messageType, } auto *notifications = this->notifications(); - if (message && notifications && - now(CLOCK_MONOTONIC) > blockNotificationBefore_) { + const auto current = now(CLOCK_MONOTONIC); + if (message && notifications && current > silenceNotificationUntil_ && + (current < allowNotificationUntil_ && + (allowNotificationType_.empty() || + messageType == allowNotificationType_))) { notifications->call( tipId, _("Rime"), icon, _("Rime"), message, timeout); } // Block message after error / success. if (blockMessage) { - blockNotificationFor(30000); + silenceNotificationUntil_ = current + 30000; } } @@ -683,12 +688,16 @@ void RimeEngine::deploy() { RIME_DEBUG() << "Rime Deploy"; releaseAllSession(true); api_->finalize(); + allowNotification(); rimeStart(true); } -void RimeEngine::sync() { +void RimeEngine::sync(bool userTriggered) { RIME_DEBUG() << "Rime Sync user data"; releaseAllSession(true); + if (userTriggered) { + allowNotification(); + } api_->sync_user_data(); } @@ -757,7 +766,6 @@ void RimeEngine::updateSchemaMenu() { schemaAction.connect( [this, schemaId](InputContext *ic) { auto *state = this->state(ic); - blockNotificationFor(30000); state->selectSchema(schemaId); imAction_->update(ic); }); diff --git a/src/rimeengine.h b/src/rimeengine.h index 8a25c7a..a4dcb5d 100644 --- a/src/rimeengine.h +++ b/src/rimeengine.h @@ -167,7 +167,7 @@ class RimeEngine final : public InputMethodEngineV2 { FCITX_ADDON_DEPENDENCY_LOADER(dbus, instance_->addonManager()); #endif - void blockNotificationFor(uint64_t usec); + void allowNotification(std::string type = ""); const auto &schemas() const { return schemas_; } const auto &optionActions() const { return optionActions_; }; @@ -177,7 +177,7 @@ class RimeEngine final : public InputMethodEngineV2 { const char *messageValue); void deploy(); - void sync(); + void sync(bool userTriggered); void updateSchemaMenu(); void updateActionsForSchema(const std::string &schema); void notifyImmediately(RimeSessionId session, std::string_view type, @@ -199,8 +199,9 @@ class RimeEngine final : public InputMethodEngineV2 { EventDispatcher eventDispatcher_; rime_api_t *api_; static bool firstRun_; - uint64_t blockNotificationBefore_ = 0; - uint64_t lastKeyEventTime_ = 0; + uint64_t silenceNotificationUntil_ = 0; + uint64_t allowNotificationUntil_ = 0; + std::string allowNotificationType_; FactoryFor factory_; bool needRefreshAppOption_ = false;