From a2af260d806a726c5f2c14b943a26c77b5a60dd9 Mon Sep 17 00:00:00 2001 From: aeoform <2790848120@qq.com> Date: Thu, 4 Jun 2026 00:07:43 +0800 Subject: [PATCH] chore(linux): plugin check improvements + remove startup shell + fix i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ensure_plugin_installed: check ~/.local/ XDG paths in addition to system paths; warn when both user and system plugins coexist (old user version takes priority over newly installed system version) - App.tsx: remove StartupShell loading screen and 'checking' gate state, app renders FloatingShell immediately - i18n: "切换上一次风格" → "切换到上一个风格" (zh-CN/zh-TW) Co-Authored-By: Claude Opus 4.7 (1M context) --- openless-all/app/src-tauri/src/linux_fcitx.rs | 48 ++++++++++---- openless-all/app/src/App.tsx | 62 +------------------ openless-all/app/src/i18n/zh-CN.ts | 2 +- openless-all/app/src/i18n/zh-TW.ts | 2 +- 4 files changed, 41 insertions(+), 73 deletions(-) diff --git a/openless-all/app/src-tauri/src/linux_fcitx.rs b/openless-all/app/src-tauri/src/linux_fcitx.rs index b3811c67..c99faa41 100644 --- a/openless-all/app/src-tauri/src/linux_fcitx.rs +++ b/openless-all/app/src-tauri/src/linux_fcitx.rs @@ -422,7 +422,7 @@ pub fn start_dictation_signal_listener( /// 未安装时输出警告,不做任何文件 I/O。 #[cfg(target_os = "linux")] pub fn ensure_plugin_installed(_app: &tauri::AppHandle) { - // fcitx5 在不同发行版的 lib 路径不同 + // fcitx5 在不同发行版的 lib 路径不同,同时支持用户 XDG 安装 let lib_dirs = [ "/usr/lib/x86_64-linux-gnu/fcitx5", // Debian multiarch "/usr/lib64/fcitx5", // RPM 64-bit @@ -430,24 +430,48 @@ pub fn ensure_plugin_installed(_app: &tauri::AppHandle) { ]; let system_conf = std::path::Path::new("/usr/share/fcitx5/addon/openless.conf"); - if !system_conf.exists() { + // 用户 XDG 安装:~/.local/ 下自编译安装的版本 + let (user_so, user_conf) = if let Ok(home) = std::env::var("HOME") { + let home = std::path::PathBuf::from(home); + ( + home.join(".local/lib/fcitx5/libopenless.so"), + home.join(".local/share/fcitx5/addon/openless.conf"), + ) + } else { + (std::path::PathBuf::new(), std::path::PathBuf::new()) + }; + + let conf_ok = user_conf.exists() || system_conf.exists(); + let system_so_found = lib_dirs.iter().find(|dir| { + std::path::Path::new(dir).join("libopenless.so").exists() + }); + let so_ok = user_so.exists() || system_so_found.is_some(); + + // 用户手动安装过 ~/.local/ 版本,同时系统路径也有(deb 注入的)→ + // fcitx5 优先加载用户路径的旧版,系统新版被忽略。 + // 提醒用户删除 ~/.local/ 的旧插件。 + if user_so.exists() && system_so_found.is_some() { log::warn!( - "[fcitx] fcitx5 addon config not installed at {:?}. \ - The OpenLess package may be incomplete.", - system_conf + "[fcitx] fcitx5 plugin found in both ~/.local/ and system paths. \ + fcitx5 will load the ~/.local/ version first, which may be outdated. \ + Remove it if you want to use the system-installed version: rm -f {}", + user_so.display() ); - return; } - let found = lib_dirs.iter().any(|dir| { - std::path::Path::new(dir).join("libopenless.so").exists() - }); + if !conf_ok { + log::warn!( + "[fcitx] fcitx5 addon config not found. \ + The OpenLess package may be incomplete." + ); + return; + } - if !found { + if !so_ok { log::warn!( - "[fcitx] fcitx5 plugin .so not found in any of {:?}. \ + "[fcitx] fcitx5 plugin .so not found in {:?} or {:?}. \ The OpenLess package may be incomplete.", - lib_dirs + lib_dirs, user_so ); } } diff --git a/openless-all/app/src/App.tsx b/openless-all/app/src/App.tsx index c3eb54f5..4ac85447 100644 --- a/openless-all/app/src/App.tsx +++ b/openless-all/app/src/App.tsx @@ -17,7 +17,6 @@ import { windowMouseHotkeyCode, } from './lib/windowHotkeyFallback'; import { QaPanel } from './pages/QaPanel'; -import { invoke } from '@tauri-apps/api/core'; import { HotkeySettingsProvider } from './state/HotkeySettingsContext'; interface AppProps { @@ -26,7 +25,7 @@ interface AppProps { forcedOs?: OS | null; } -type Gate = 'checking' | 'onboarding' | 'ready'; +type Gate = 'onboarding' | 'ready'; export function App({ isCapsule, isQa, forcedOs }: AppProps) { if (isCapsule) { @@ -38,11 +37,10 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) { const os = forcedOs ?? detectOS(); // Windows 启动不应被权限探测阻塞首屏。 - const [gate, setGate] = useState(isTauri ? 'checking' : 'ready'); + const [gate, setGate] = useState(isTauri ? 'ready' : 'ready'); useEffect(() => { if (!isTauri) return; - if (os === 'win' && gate === 'checking') return; let cancelled = false; requestAnimationFrame(() => { if (cancelled) return; @@ -80,7 +78,7 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) { return () => { cancelled = true; }; - }, [gate, os]); + }, [os]); useEffect(() => { if (!isTauri) return; @@ -170,21 +168,6 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) { }; }, [os]); - // Linux: 检测 WEBKIT_DISABLE_COMPOSITING_MODE → 禁用 backdrop-filter fallback - useEffect(() => { - if (!isTauri) return; - invoke('is_no_compositing_mode').then((val) => { - if (val) { - document.documentElement.dataset.olNoCompositing = 'true'; - } - }).catch((err) => { - console.warn('[startup] is_no_compositing_mode failed', err); - }); - }, []); - - if (gate === 'checking') { - return ; - } return ( {gate === 'onboarding' ? setGate('ready')} /> : } @@ -193,42 +176,3 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) { ); } -function StartupShell() { - // 用透明背景:main window 是 transparent + macOSPrivateApi(NSVisualEffectView 磨砂)。 - // 之前用 linear-gradient(rgba(245,245,247,0.96)...) 会盖过 macOS vibrancy,启动时 - // 长时间在 'checking' phase(凭据迁移 / 权限 probe 慢)会让窗口看起来「左侧白屏 + - // 右侧磨砂」割裂。现在背景全透明,让磨砂统一展开,提示文字 + icon 用一个轻量 - // pill 卡片承载,跟 capsule 视觉一致。 - return ( -
-
- - OpenLess 正在启动 -
-
- ); -} diff --git a/openless-all/app/src/i18n/zh-CN.ts b/openless-all/app/src/i18n/zh-CN.ts index ca387876..3d2df8e3 100644 --- a/openless-all/app/src/i18n/zh-CN.ts +++ b/openless-all/app/src/i18n/zh-CN.ts @@ -680,7 +680,7 @@ export const zhCN = { startStop: '开始 / 停止录音', cancel: '取消本次录音', confirm: '胶囊确认插入', - switchStyle: '切换上一次风格', + switchStyle: '切换到上一个风格', openApp: '打开 OpenLess', confirmHint: '点击右侧 ✓', notSupported: '暂未支持', diff --git a/openless-all/app/src/i18n/zh-TW.ts b/openless-all/app/src/i18n/zh-TW.ts index 043e71b9..00f8faf8 100644 --- a/openless-all/app/src/i18n/zh-TW.ts +++ b/openless-all/app/src/i18n/zh-TW.ts @@ -682,7 +682,7 @@ export const zhTW: typeof zhCN = { startStop: '開始 / 停止錄音', cancel: '取消本次錄音', confirm: '膠囊確認插入', - switchStyle: '切換上一次風格', + switchStyle: '切換到上一個風格', openApp: '打開 OpenLess', confirmHint: '點擊右側 ✓', notSupported: '暫未支持',