diff --git a/src/modules/notificationitem/notificationitem.cpp b/src/modules/notificationitem/notificationitem.cpp index b94f7789e..08a31b5fc 100644 --- a/src/modules/notificationitem/notificationitem.cpp +++ b/src/modules/notificationitem/notificationitem.cpp @@ -72,6 +72,14 @@ class StatusNotifierItem : public dbus::ObjectVTable { std::string label() { return ""; } + std::string title() { + const InputMethodEntry *imEntry = nullptr; + if (auto *ic = parent_->menu()->lastRelevantIc()) { + imEntry = parent_->instance()->inputMethodEntry(ic); + } + return imEntry == nullptr ? _("Input Method") : imEntry->name(); + } + static dbus::DBusStruct< std::string, std::vector>>, @@ -104,6 +112,15 @@ class StatusNotifierItem : public dbus::ObjectVTable { lastLabel_ = std::move(label); } + void notifyNewTitle() { + std::string currentTitle = title(); + if (currentTitle.empty() || lastTitle_ == currentTitle) { + return; + } + newTitle(); + lastTitle_ = std::move(currentTitle); + } + void reset() { releaseSlot(); lastIconName_.clear(); @@ -139,7 +156,7 @@ class StatusNotifierItem : public dbus::ObjectVTable { []() { return "SystemServices"; }); FCITX_OBJECT_VTABLE_PROPERTY(id, "Id", "s", []() { return "Fcitx"; }); FCITX_OBJECT_VTABLE_PROPERTY(title, "Title", "s", - []() { return _("Input Method"); }); + [this]() { return title(); }); FCITX_OBJECT_VTABLE_PROPERTY(status, "Status", "s", []() { return "Active"; }); FCITX_OBJECT_VTABLE_PROPERTY(windowId, "WindowId", "i", []() { return 0; }); @@ -238,6 +255,7 @@ class StatusNotifierItem : public dbus::ObjectVTable { std::string cachedLabel_; std::vector>> cachedLabelIcon_; + std::string lastTitle_; }; NotificationItem::NotificationItem(Instance *instance) @@ -280,26 +298,27 @@ void NotificationItem::setRegistered(bool registered) { registered_ = registered; if (registered_) { - auto updateIcon = [this](Event &e) { + auto updateIconAndTitle = [this](Event &e) { InputContext *ic = nullptr; if (e.isInputContextEvent()) { ic = dynamic_cast(e).inputContext(); } menu_->updateMenu(ic); newIcon(); + newTitle(); }; for (auto type : {EventType::InputContextFocusIn, EventType::InputContextSwitchInputMethod, EventType::InputMethodGroupChanged}) { eventHandlers_.emplace_back(instance_->watchEvent( - type, EventWatcherPhase::Default, updateIcon)); + type, EventWatcherPhase::Default, updateIconAndTitle)); } eventHandlers_.emplace_back(instance_->watchEvent( EventType::InputContextFlushUI, EventWatcherPhase::Default, - [updateIcon](Event &event) { + [updateIconAndTitle](Event &event) { if (static_cast(event) .component() == UserInterfaceComponent::StatusArea) { - updateIcon(event); + updateIconAndTitle(event); } })); } @@ -406,6 +425,13 @@ void NotificationItem::newIcon() { // sni_->xayatanaNewLabel(sni_->label(), sni_->label()); } +void NotificationItem::newTitle() { + if (!sni_->isRegistered()) { + return; + } + sni_->notifyNewTitle(); +} + class NotificationItemFactory : public AddonFactory { AddonInstance *create(AddonManager *manager) override { return new NotificationItem(manager->instance()); diff --git a/src/modules/notificationitem/notificationitem.h b/src/modules/notificationitem/notificationitem.h index def6b0dff..3cd743ec6 100644 --- a/src/modules/notificationitem/notificationitem.h +++ b/src/modules/notificationitem/notificationitem.h @@ -36,7 +36,6 @@ class NotificationItem : public AddonInstance { bool registered() const { return registered_; } std::unique_ptr> watch(NotificationItemCallback callback); - void newIcon(); FCITX_ADDON_DEPENDENCY_LOADER(classicui, instance_->addonManager()); DBusMenu *menu() { return menu_.get(); } @@ -49,6 +48,8 @@ class NotificationItem : public AddonInstance { void maybeScheduleRegister(); void cleanUp(); + void newIcon(); + void newTitle(); Instance *instance_; std::unique_ptr watcher_;