Skip to content

Commit

Permalink
Change the notification mechanism to allow list mode
Browse files Browse the repository at this point in the history
Only allow notification if:
1. action triggered by user, either via action, or shortcut, or
   setSubConfig.
2. error on start up.
  • Loading branch information
wengxt committed Jan 23, 2025
1 parent 9155bf3 commit f299e60
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 23 deletions.
2 changes: 0 additions & 2 deletions src/rimeaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
42 changes: 25 additions & 17 deletions src/rimeengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <fcitx-config/iniparser.h>
#include <fcitx-config/rawconfig.h>
#include <fcitx-utils/event.h>
#include <fcitx-utils/eventloopinterface.h>
#include <fcitx-utils/fs.h>
#include <fcitx-utils/i18n.h>
#include <fcitx-utils/log.h>
Expand Down Expand Up @@ -53,6 +54,9 @@ namespace fcitx::rime {

namespace {

// Allow notification for 60secs.
constexpr uint64_t NotificationTimeout = 60000000;

std::unordered_map<std::string, std::unordered_map<std::string, bool>>
parseAppOptions(rime_api_t *api, RimeConfig *config) {
std::unordered_map<std::string, std::unordered_map<std::string, bool>>
Expand Down Expand Up @@ -210,7 +214,7 @@ RimeEngine::RimeEngine(Instance *instance)
syncAction_.setShortText(_("Synchronize"));

syncAction_.connect<SimpleAction::Activated>([this](InputContext *ic) {
sync();
sync(/*userTriggered=*/true);
auto *state = this->state(ic);
if (state && ic->hasFocus()) {
state->updateUI(ic, false);
Expand All @@ -224,6 +228,8 @@ RimeEngine::RimeEngine(Instance *instance)
globalConfigReloadHandle_ = instance_->watchEvent(
EventType::GlobalConfigReloaded, EventWatcherPhase::Default,
[this](Event &) { refreshSessionPoolPolicy(); });

allowNotification("failure");
reloadConfig();
constructed_ = true;
}
Expand Down Expand Up @@ -335,7 +341,7 @@ void RimeEngine::setSubConfig(const std::string &path,
if (path == "deploy") {
deploy();
} else if (path == "sync") {
sync();
sync(/*userTriggered=*/true);
}
}

Expand Down Expand Up @@ -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();
Expand All @@ -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();
}
}
Expand All @@ -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,
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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<INotifications::showTip>(
tipId, _("Rime"), icon, _("Rime"), message, timeout);
}
// Block message after error / success.
if (blockMessage) {
blockNotificationFor(30000);
silenceNotificationUntil_ = current + 30000;
}
}

Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -757,7 +766,6 @@ void RimeEngine::updateSchemaMenu() {
schemaAction.connect<SimpleAction::Activated>(
[this, schemaId](InputContext *ic) {
auto *state = this->state(ic);
blockNotificationFor(30000);
state->selectSchema(schemaId);
imAction_->update(ic);
});
Expand Down
9 changes: 5 additions & 4 deletions src/rimeengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_; };

Expand All @@ -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,
Expand All @@ -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<RimeState> factory_;
bool needRefreshAppOption_ = false;

Expand Down

0 comments on commit f299e60

Please sign in to comment.