Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
2912aef
feat(linux): replace enigo with fcitx5 plugin for Wayland input
aeoform May 15, 2026
a1b7a2a
fix(linux): cfg-gate linux_fcitx module + skip capsule window on Wayland
aeoform May 15, 2026
4f1e457
feat(ci): build fcitx5 plugin into Linux deb/rpm packages
aeoform May 15, 2026
dfced4f
fix(linux): sync fcitx5 plugin hotkey binding on update
aeoform May 15, 2026
85c2caf
fix(ci): use cmake-determined plugin install path in deb
aeoform May 15, 2026
07132c2
fix(linux): track fcitx5 InputContext lifetime via destroyed signal
aeoform May 15, 2026
dbae3b7
fix(linux): correct fcitx5 InputContext::destroyed signal connection …
aeoform May 15, 2026
acfdd39
fix(linux): unify on fcitx5 for both Wayland and X11, drop enigo
aeoform May 15, 2026
b349a4d
fix(linux): remove dead rdev code and leftover Wayland references
aeoform May 16, 2026
323dbed
fix(linux): add QA and translation modifier hotkey support to fcitx5 …
aeoform May 16, 2026
60250c8
fix(linux): support custom combo hotkeys and surface fcitx5 errors
aeoform May 16, 2026
088e2ab
fix(ci): derive RPM fcitx5 plugin path from cmake detection
aeoform May 16, 2026
416da60
fix(linux): allow single-key custom triggers in fcitx5 plugin sync
aeoform May 16, 2026
9cd8b9a
fix(linux): clear previous hotkey trigger when switching between cust…
aeoform May 16, 2026
f043176
fix(linux): correct Fn hotkey mapping from Super_L to RightControl
aeoform May 16, 2026
39ce12c
Merge remote-tracking branch 'origin/beta' into beta — resolve coordi…
aeoform May 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 62 additions & 6 deletions .github/workflows/release-tauri.yml
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,37 @@ jobs:
throw "MSI installer smoke failed with exit $LASTEXITCODE"
}

# ── Linux:产 deb / rpm / AppImage ──
# bundle.resources 里的 Windows TSF DLL 占位对 Linux 包没意义,用空 map 覆盖跳过。
# ── Linux:先编译 fcitx5 插件,再产 deb / rpm / AppImage ──
- name: Build fcitx5 plugin
if: matrix.platform == 'ubuntu-22.04'
shell: bash
working-directory: 'openless-all/scripts/linux-fcitx5-plugin'
run: |
sudo apt-get install -y cmake fcitx5-dev
mkdir -p build && cd build
cmake .. 2>&1
make
# 从 cmake 缓存中读出 distro 实际的插件安装路径(multiarch 感知)。
FCITX_ADDON_DIR=$(cmake -LA . 2>/dev/null \
| grep "^FCITX_INSTALL_ADDONDIR:" \
| cut -d= -f2)
FCITX_PKGDATA_DIR=$(cmake -LA . 2>/dev/null \
| grep "^FCITX_INSTALL_PKGDATADIR:" \
| cut -d= -f2)
echo "Detected: addon=$FCITX_ADDON_DIR pkgdata=$FCITX_PKGDATA_DIR"
echo "FCITX_ADDON_DIR=$FCITX_ADDON_DIR" >> "$GITHUB_ENV"
echo "FCITX_ADDON_CONF_DIR=${FCITX_PKGDATA_DIR}/addon" >> "$GITHUB_ENV"
# 对 RPM 目标映射路径:Debian multiarch(如 /usr/lib/x86_64-linux-gnu)
# -> /usr/lib64(RPM 标准)。conf 路径跨发行版一致。
RPM_ADDON_DIR=$(echo "$FCITX_ADDON_DIR" \
| sed 's|/usr/lib/[^/]*/fcitx5|/usr/lib64/fcitx5|;s|/usr/lib/x86_64-linux-gnu/fcitx5|/usr/lib64/fcitx5|')
echo "FCITX_RPM_ADDON_DIR=$RPM_ADDON_DIR" >> "$GITHUB_ENV"
# 把插件 .so + .conf 复制到 src-tauri/linux-fcitx5-plugin/ 下面,
# 供 tauri deb/rpm bundler 的 files 配置使用。
mkdir -p "$GITHUB_WORKSPACE/openless-all/app/src-tauri/linux-fcitx5-plugin"
cp libopenless.so "$GITHUB_WORKSPACE/openless-all/app/src-tauri/linux-fcitx5-plugin/"
cp openless.conf "$GITHUB_WORKSPACE/openless-all/app/src-tauri/linux-fcitx5-plugin/"

- name: Build (Linux)
if: matrix.platform == 'ubuntu-22.04'
shell: bash
Expand All @@ -349,13 +378,40 @@ jobs:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: |
# 构建带 fcitx5 插件的 deb/rpm。AppImage 不含插件(无法安装系统路径),
# 用户需手动安装脚本 scripts/linux-fcitx5-plugin/build.sh 输出的 .so 和 .conf。
# 插件 .so + .conf 由上一步 Build fcitx5 plugin 生成并复制到
# src-tauri/linux-fcitx5-plugin/ 下。
cat > /tmp/tauri-linux-config.json << CONFIG_EOF
{
"bundle": {
"resources": {},
"linux": {
"deb": {
"depends": ["fcitx5", "fcitx5-module-dbus", "libdbus-1-3"],
"files": {
"${FCITX_ADDON_DIR}/libopenless.so": "linux-fcitx5-plugin/libopenless.so",
"${FCITX_ADDON_CONF_DIR}/openless.conf": "linux-fcitx5-plugin/openless.conf"
}
},
"rpm": {
"depends": ["fcitx5", "fcitx5-module-dbus"],
"files": {
"${FCITX_RPM_ADDON_DIR}/libopenless.so": "linux-fcitx5-plugin/libopenless.so",
"${FCITX_ADDON_CONF_DIR}/openless.conf": "linux-fcitx5-plugin/openless.conf"
}
}
}
}
}
CONFIG_EOF
if [ -n "${TAURI_SIGNING_PRIVATE_KEY:-}" ]; then
npm run tauri -- build --bundles deb,rpm,appimage \
--config '{"bundle":{"resources":{},"createUpdaterArtifacts":true}}'
jq '.bundle.createUpdaterArtifacts = true' /tmp/tauri-linux-config.json > /tmp/tauri-linux-config-signed.json
CONFIG_FILE=/tmp/tauri-linux-config-signed.json
else
npm run tauri -- build --bundles deb,rpm,appimage \
--config '{"bundle":{"resources":{}}}'
CONFIG_FILE=/tmp/tauri-linux-config.json
fi
npm run tauri -- build --bundles deb,rpm,appimage --config "$CONFIG_FILE"

- name: Disambiguate macOS updater bundle filename
if: startsWith(matrix.platform, 'macos') && env.TAURI_SIGNING_PRIVATE_KEY != ''
Expand Down
123 changes: 11 additions & 112 deletions openless-all/app/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion openless-all/app/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ global-hotkey = "0.6"
cpal = "0.15"
enigo = "0.2"
arboard = "3"
rdev = "0.5"

[target.'cfg(target_os = "macos")'.dependencies.keyring]
version = "3.6.3"
Expand All @@ -62,6 +61,8 @@ version = "3.6.3"
default-features = false
features = ["windows-native"]

[target.'cfg(target_os = "linux")'.dependencies]
dbus = "0.9"
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies.keyring]
version = "3.6.3"
default-features = false
Expand Down
5 changes: 1 addition & 4 deletions openless-all/app/src-tauri/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
//! 极简 CLI 参数解析 — 用于支持桌面环境快捷键调起 OpenLess 触发听写 / QA。
//!
//! 这条路径的来历:Linux Wayland 协议层面禁止"应用监听全局键盘"(除了焦点窗口),
//! 因此 rdev 在 Wayland 上必然失效(issue #420)。本仓库不为 Wayland 引入门户
//! GlobalShortcuts(GNOME 尚未原生落地,引入会增加合成器分裂的维护负担——见
//! `docs/issue-420-wayland-hotkey-research.md` 3.1 节),改走桌面环境快捷键 →
//! 这条路径的来历:Linux 上 fcitx5 插件提供了热键 + 文字提交的完整方案,
//! `openless --toggle-dictation` → tauri-plugin-single-instance 转发的 CLI 路径。
//! macOS / Windows 上仍走原生 hotkey 监听器,CLI 是补充而非替代。
//!
Expand Down
12 changes: 0 additions & 12 deletions openless-all/app/src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,18 +484,6 @@ pub fn get_hotkey_capability(coord: CoordinatorState<'_>) -> HotkeyCapability {
coord.hotkey_capability()
}

/// Pull-style 查询:当前是否处于 Linux/Wayland session(rdev 不可用、需要走 CLI 路径)。
/// 前端 RecordingSection mount 时调一次拿状态,直接渲染 callout。
///
/// 用 pull 而不是单纯依赖 ready-time 的 `wayland_cli_mode` event:Settings 模态是
/// 条件渲染(用户首次打开 Settings 才 mount RecordingSection),但 emit 发生在 setup
/// 末尾——一次性 event 不缓冲也不 replay,listener 99% 情况下错过事件 → callout
/// 永远不显示。XDG_SESSION_TYPE 本身在进程生命周期内不会变,多次调用结果一致。
#[tauri::command]
pub fn is_wayland_cli_mode() -> bool {
crate::hotkey::is_wayland_session()
}

#[tauri::command]
pub fn set_shortcut_recording_active(coord: CoordinatorState<'_>, active: bool) {
coord.set_shortcut_recording_active(active);
Expand Down
Loading