feat(linux): 选区读取集成进 fcitx5 插件(clipboard addon),删除外部工具依赖 (#961)

* feat(linux): 选区读取集成进 fcitx5 插件(clipboard addon),删除外部工具依赖

- openless 插件新增 GetSelectionText DBus 方法:直读 fcitx clipboard addon
  的 PRIMARY 选区缓存(X11 XFIXES / Wayland data-control 统一维护),与
  fcitx 剪贴板模块来源一致,不触碰用户剪贴板
- CMake 增加 Fcitx5::Module::Clipboard 依赖
- Rust 侧 selection 改走插件 GetSelectionText,删除 wl-paste/xclip/xsel
  外部工具路径及 linux_selection_tools_missing 提醒机制(前端
  selection_warning 状态机、i18n、测试一并删除)
- acceptQaSessionEvent 的 idle 分支不再依赖 selection_warning 字段,
  一律视为新会话 token(事件保序,语义等价)
- 打字提问路径(QA 面板 / less-computer)不再 emit Polishing capsule:
  回答在面板内可见,避免 Linux 输入法 auxDown 闪「✨ 润色中...」

(cherry picked from commit 384f8876a490cb3e8e992af05cdad33f2af6a8ec)

* fix(linux): bundle and sync fcitx5 selection plugin

(cherry picked from commit 7e8bf825c08f5e935c7a25746c121136d92b7926)

* fix(linux): use DBus selection reader during validation

(cherry picked from commit d13403343b08fe1b4070e0f0d2f219a0a69d363e)

* refactor(linux): 收尾 PR 961 审查发现的小毛病

- capsule 反馈参数从裸 bool 改为具名枚举 CapsuleFeedback(Show/Hide):
  语音/听写路径 Show、打字路径 Hide,调用点自文档化,避免将来误传
- AppImage 插件子路径提取为 APPIMAGE_PLUGIN_SUBDIR 常量并注明与 CI
  bundle.resources 的契约,避免三处硬编码静默失配
- selection.rs 移除文件级 Linux 大赦(lib.rs 的 crate 级兜底仍在),
  Duration import 按平台限定,消除 Linux unused 隐患

---------

Co-authored-by: Chris233 <h-chris233@outlook.com>
This commit is contained in:
aeoformandChris233 authored and GitHub committed 2026-08-19 20:34:10 +08:00
1 parent 789c82051e
commit 33467a36ea
21 files changed
+587 -238

No files matched your search

+1 -2
View File
@@ -3,8 +3,7 @@
# Usage: ./inject-fcitx5-plugin.sh <package-path>
#
# Supports: .deb, .rpm
# AppImage is NOT supported — fcitx5 runs on the host and cannot load
# addons from inside the AppImage mount.
# AppImage resources are bundled separately and installed to ~/.local/ at runtime.
set -euo pipefail
PKG="$1"
@@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Fcitx5Core REQUIRED)
find_package(Fcitx5Utils REQUIRED)
find_package(Fcitx5Module REQUIRED COMPONENTS DBus)
find_package(Fcitx5Module REQUIRED COMPONENTS DBus Clipboard)
# FCITX_INSTALL_*DIR comes from Fcitx5Utils
message(STATUS "FCITX_INSTALL_LIBDIR: ${FCITX_INSTALL_LIBDIR}")
@@ -16,7 +16,8 @@ message(STATUS "FCITX_INSTALL_ADDONDIR: ${FCITX_INSTALL_ADDONDIR}")
add_library(openless MODULE openless.cpp)
target_link_libraries(openless PRIVATE
Fcitx5::Core
Fcitx5::Utils)
Fcitx5::Utils
Fcitx5::Module::Clipboard)
# Locate fcitx5 module headers (e.g. fcitx-module/dbus/dbus_public.h)
find_path(FCITX5_MODULE_INCLUDE_DIR
@@ -18,6 +18,7 @@
* SetTranslationHotkeyRaw(uu: sym, states) — 直接设翻译模式触发 sym+states
* SetAuxDown(s: text) — 在候选词列表下方显示状态文本
* ClearAuxDown() — 清除候选词列表下方文本
* GetSelectionText() -> s — 读取当前 PRIMARY 选区文本(由 clipboard addon 维护)
* 信号:
* DictationKeyEvent(uub: sym, states, isPress) — 听写热键按下/抬起
* QaShortcutEvent(uub: sym, states, isPress) — QA 快捷键按下/抬起
@@ -46,6 +47,7 @@
#include <fcitx/inputcontextmanager.h>
#include <fcitx/inputpanel.h>
#include <fcitx/instance.h>
#include <fcitx-module/clipboard/clipboard_public.h>
#include <fcitx-module/dbus/dbus_public.h>
FCITX_DEFINE_LOG_CATEGORY(openless, "openless");
@@ -454,6 +456,22 @@ public:
<< "SetTranslationHotkeyRaw: sym=" << sym << " states=" << states;
}
/// 读取当前 PRIMARY 选区文本。空字符串表示无选区或 clipboard addon 不可用。
std::string getSelectionText() {
auto *clipboard = instance_->addonManager().addon("clipboard");
if (!clipboard) {
FCITX_LOGC(openless, Debug)
<< "GetSelectionText: clipboard addon not loaded";
return std::string();
}
// primary() 签名接收 const InputContext*,clipboard 模块实现中未使用该参数
// (读的是全局 primary_ 缓存),这里传 nullptr 即可。
std::string text = clipboard->call<IClipboard::primary>(nullptr);
FCITX_LOGC(openless, Debug)
<< "GetSelectionText: " << text.size() << " chars";
return text;
}
FCITX_OBJECT_VTABLE_METHOD(commitText, "CommitText", "s", "");
FCITX_OBJECT_VTABLE_METHOD(setAuxDown, "SetAuxDown", "s", "");
FCITX_OBJECT_VTABLE_METHOD(clearAuxDown, "ClearAuxDown", "", "");
@@ -463,6 +481,7 @@ public:
FCITX_OBJECT_VTABLE_METHOD(setQaHotkeyRaw, "SetQaHotkeyRaw", "uu", "");
FCITX_OBJECT_VTABLE_METHOD(setSelectionPolishHotkeyRaw, "SetSelectionPolishHotkeyRaw", "uu", "");
FCITX_OBJECT_VTABLE_METHOD(setTranslationHotkeyRaw, "SetTranslationHotkeyRaw", "uu", "");
FCITX_OBJECT_VTABLE_METHOD(getSelectionText, "GetSelectionText", "", "s");
FCITX_OBJECT_VTABLE_SIGNAL(dictationKeyEvent, "DictationKeyEvent", "uub");
FCITX_OBJECT_VTABLE_SIGNAL(dictationKeyCombined, "DictationKeyCombined", "uub");
FCITX_OBJECT_VTABLE_SIGNAL(qaShortcutEvent, "QaShortcutEvent", "uub");