diff --git a/src/frontend/dbusfrontend/dbusfrontend.cpp b/src/frontend/dbusfrontend/dbusfrontend.cpp index 8e2a5557f..ade9b761c 100644 --- a/src/frontend/dbusfrontend/dbusfrontend.cpp +++ b/src/frontend/dbusfrontend/dbusfrontend.cpp @@ -29,6 +29,7 @@ #include "fcitx-utils/rect.h" #include "fcitx/addonfactory.h" #include "fcitx/addoninstance.h" +#include "fcitx/candidatelist.h" #include "fcitx/event.h" #include "fcitx/inputcontext.h" #include "fcitx/inputmethodentry.h" @@ -225,10 +226,18 @@ class DBusInputContext1 : public InputContext, return; } - auto preedit = instance->outputFilter(this, inputPanel().preedit()); - auto auxUp = instance->outputFilter(this, inputPanel().auxUp()); - auto auxDown = instance->outputFilter(this, inputPanel().auxDown()); - auto candidateList = inputPanel().candidateList(); + Text preedit; + Text auxUp; + Text auxDown; + std::shared_ptr candidateList; + if (!inputPanel().empty()) { + preedit = instance->outputFilter(this, inputPanel().preedit()); + auxUp = instance->outputFilter(this, inputPanel().auxUp()); + auxDown = instance->outputFilter(this, inputPanel().auxDown()); + candidateList = inputPanel().candidateList(); + } else if (!inputPanel().overlayMessage().empty()) { + auxUp = inputPanel().overlayMessage(); + } int cursorIndex = 0; preeditStrings = buildFormattedTextVector(preedit); diff --git a/src/lib/fcitx/inputpanel.cpp b/src/lib/fcitx/inputpanel.cpp index 376c12e25..1a0000bcb 100644 --- a/src/lib/fcitx/inputpanel.cpp +++ b/src/lib/fcitx/inputpanel.cpp @@ -20,6 +20,7 @@ class InputPanelPrivate { Text auxUp_; Text preedit_; Text clientPreedit_; + Text overlayMessage_; std::shared_ptr candidate_; InputContext *ic_; CustomInputPanelCallback customCallback_ = nullptr; @@ -84,6 +85,16 @@ const Text &InputPanel::preedit() const { return d->preedit_; } +const Text &InputPanel::overlayMessage() const { + FCITX_D(); + return d->overlayMessage_; +} + +void InputPanel::setOverlayMessage(Text text) { + FCITX_D(); + d->overlayMessage_ = std::move(text); +} + const CustomInputPanelCallback &InputPanel::customInputPanelCallback() const { FCITX_D(); return d->customCallback_; @@ -115,6 +126,7 @@ void InputPanel::reset() { d->candidate_.reset(); d->auxUp_.clear(); d->auxDown_.clear(); + d->overlayMessage_.clear(); d->customCallback_ = nullptr; d->customVirtualKeyboardCallback_ = nullptr; } diff --git a/src/lib/fcitx/inputpanel.h b/src/lib/fcitx/inputpanel.h index ac2681c19..ce0bd17c9 100644 --- a/src/lib/fcitx/inputpanel.h +++ b/src/lib/fcitx/inputpanel.h @@ -8,8 +8,11 @@ #define _FCITX_INPUTPANEL_H_ #include +#include +#include #include #include +#include /// \addtogroup FcitxCore /// \{ @@ -67,6 +70,41 @@ class FCITXCORE_EXPORT InputPanel { std::shared_ptr candidateList() const; void setCandidateList(std::unique_ptr candidate); + /** + * An text message that allows the input method to display a message on top + * of the input panel. + * + * When not empty, it should behave as if it is displayed in aux up. + * + * If you just need a naive implementation with timeout, consider using + * Instance::showCustomInputMethodInformation. + * + * This is intended to be used by a third party to display some message when + * engine/temp mode is controlling the input panel. + * + * This message should still be considered as temporary and + * InputPanel::reset will still clear it when the input panel current owner + * want to reset. + * + * @see Instance::showInputMethodInformation + * @see Instance::showCustomInputMethodInformation + * + * @since 5.1.22 + */ + const Text &overlayMessage() const; + + /** + * Set an overlay message on the input panel. + * + * It will not be shown if input panel has content, otherwise it will be + * shown as if it is in aux up. + * + * @param text the message to display. + * + * @since 5.1.22 + */ + void setOverlayMessage(Text text); + /** * Return the current input panel display callback. * diff --git a/src/lib/fcitx/instance.cpp b/src/lib/fcitx/instance.cpp index 37c5f0bba..c28766dcc 100644 --- a/src/lib/fcitx/instance.cpp +++ b/src/lib/fcitx/instance.cpp @@ -519,7 +519,7 @@ InputState::InputState(InstancePrivate *d, InputContext *ic) } void InputState::showInputMethodInformation(const std::string &name) { - ic_->inputPanel().setAuxUp(Text(name)); + ic_->inputPanel().setOverlayMessage(Text(name)); ic_->updateUserInterface(UserInterfaceComponent::InputPanel); lastInfo_ = name; imInfoTimer_ = d_ptr->eventLoop_.addTimeEvent( @@ -615,11 +615,9 @@ void InputState::hideInputMethodInfo() { } imInfoTimer_.reset(); auto &panel = ic_->inputPanel(); - if (panel.auxDown().empty() && panel.preedit().empty() && - panel.clientPreedit().empty() && - (!panel.candidateList() || panel.candidateList()->empty()) && - panel.auxUp().size() == 1 && panel.auxUp().stringAt(0) == lastInfo_) { - panel.reset(); + if (panel.overlayMessage().size() == 1 && + panel.overlayMessage().stringAt(0) == lastInfo_) { + panel.setOverlayMessage(Text()); ic_->updateUserInterface(UserInterfaceComponent::InputPanel); } } @@ -664,6 +662,11 @@ Instance::Instance(int argc, char **argv) { throw InstanceQuietQuit(); } + // Start logging after quietQuit to avoid spamming the log with version + // information when user just want to see the version. + FCITX_INFO() << "Starting fcitx5 " << Instance::version(); + FCITX_LOG_IF(Info, isInFlatpak()) << "Running inside flatpak."; + if (arg.runAsDaemon) { initAsDaemon(); } diff --git a/src/server/main.cpp b/src/server/main.cpp index 19dd0c172..68e1dbe12 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -17,6 +17,7 @@ #include "fcitx-utils/log.h" #include "fcitx-utils/misc.h" #include "fcitx-utils/misc_p.h" +#include "fcitx-utils/semver.h" #include "fcitx-utils/standardpath.h" #include "fcitx-utils/standardpaths.h" #include "fcitx/addonfactory.h" @@ -58,7 +59,6 @@ int main(int argc, char *argv[]) { bool restart = false; bool canRestart = false; try { - FCITX_LOG_IF(Info, isInFlatpak()) << "Running inside flatpak."; Instance instance(argc, argv); instance.setBinaryMode(); instance.setSignalPipe(selfPipe[0]); diff --git a/src/ui/classic/inputwindow.cpp b/src/ui/classic/inputwindow.cpp index db05dd4e6..d316da3a3 100644 --- a/src/ui/classic/inputwindow.cpp +++ b/src/ui/classic/inputwindow.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -360,8 +361,18 @@ std::pair InputWindow::update(InputContext *inputContext) { inputContext_ = inputContext->watch(); cursor_ = -1; - auto preedit = instance->outputFilter(inputContext, inputPanel.preedit()); - auto auxUp = instance->outputFilter(inputContext, inputPanel.auxUp()); + Text preedit; + Text auxUp; + Text auxDown; + std::shared_ptr candidateList; + if (!inputPanel.empty()) { + preedit = instance->outputFilter(inputContext, inputPanel.preedit()); + auxUp = instance->outputFilter(inputContext, inputPanel.auxUp()); + auxDown = instance->outputFilter(inputContext, inputPanel.auxDown()); + candidateList = inputPanel.candidateList(); + } else if (!inputPanel.overlayMessage().empty()) { + auxUp = inputPanel.overlayMessage(); + } pango_layout_set_single_paragraph_mode(upperLayout_.get(), true); setTextToLayout(inputContext, upperLayout_.get(), nullptr, nullptr, {auxUp, preedit}); @@ -370,11 +381,10 @@ std::pair InputWindow::update(InputContext *inputContext) { cursor_ = preedit.cursor() + auxUp.toString().size(); } - auto auxDown = instance->outputFilter(inputContext, inputPanel.auxDown()); setTextToLayout(inputContext, lowerLayout_.get(), nullptr, nullptr, {auxDown}); - if (auto candidateList = inputPanel.candidateList()) { + if (candidateList) { // Count non-placeholder candidates. int count = 0; diff --git a/src/ui/kimpanel/kimpanel.cpp b/src/ui/kimpanel/kimpanel.cpp index ca74dab7f..cf42b0778 100644 --- a/src/ui/kimpanel/kimpanel.cpp +++ b/src/ui/kimpanel/kimpanel.cpp @@ -316,8 +316,18 @@ void Kimpanel::updateInputPanel(InputContext *inputContext) { auto *instance = this->instance(); auto &inputPanel = inputContext->inputPanel(); - auto preedit = instance->outputFilter(inputContext, inputPanel.preedit()); - auto auxUp = instance->outputFilter(inputContext, inputPanel.auxUp()); + Text preedit; + Text auxUp; + Text auxDown; + std::shared_ptr candidateList; + if (!inputPanel.empty()) { + preedit = instance->outputFilter(inputContext, inputPanel.preedit()); + auxUp = instance->outputFilter(inputContext, inputPanel.auxUp()); + auxDown = instance->outputFilter(inputContext, inputPanel.auxDown()); + candidateList = inputPanel.candidateList(); + } else if (!inputPanel.overlayMessage().empty()) { + auxUp = inputPanel.overlayMessage(); + } auto preeditString = preedit.toString(); auto auxUpString = auxUp.toString(); if (!preeditString.empty() || !auxUpString.empty()) { @@ -347,9 +357,7 @@ void Kimpanel::updateInputPanel(InputContext *inputContext) { proxy_->showPreedit(false); } - auto auxDown = instance->outputFilter(inputContext, inputPanel.auxDown()); auto auxDownString = auxDown.toString(); - auto candidateList = inputPanel.candidateList(); auto msg = bus_->createMethodCall("org.kde.impanel", "/org/kde/impanel", "org.kde.impanel2", "SetLookupTable");