Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
48 changes: 36 additions & 12 deletions openless-all/app/src-tauri/src/linux_fcitx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,32 +422,56 @@ 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
"/usr/lib/fcitx5", // 通用回退
];
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
);
}
}
Expand Down
62 changes: 3 additions & 59 deletions openless-all/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {
Expand All @@ -38,11 +37,10 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) {

const os = forcedOs ?? detectOS();
// Windows 启动不应被权限探测阻塞首屏。
const [gate, setGate] = useState<Gate>(isTauri ? 'checking' : 'ready');
const [gate, setGate] = useState<Gate>(isTauri ? 'ready' : 'ready');

useEffect(() => {
if (!isTauri) return;
if (os === 'win' && gate === 'checking') return;
let cancelled = false;
requestAnimationFrame(() => {
if (cancelled) return;
Expand Down Expand Up @@ -80,7 +78,7 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) {
return () => {
cancelled = true;
};
}, [gate, os]);
}, [os]);

useEffect(() => {
if (!isTauri) return;
Expand Down Expand Up @@ -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<boolean>('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 <StartupShell />;
}
return (
<HotkeySettingsProvider>
{gate === 'onboarding' ? <Onboarding onComplete={() => setGate('ready')} /> : <FloatingShell os={os} />}
Expand All @@ -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 (
<div
style={{
minHeight: '100vh',
display: 'grid',
placeItems: 'center',
background: 'transparent',
color: 'var(--ol-ink-3)',
fontFamily: 'var(--ol-font-sans)',
}}
>
<div
style={{
display: 'flex',
alignItems: 'center',
gap: 10,
fontSize: 13,
fontWeight: 500,
padding: '10px 16px',
borderRadius: 999,
background: 'rgba(255, 255, 255, 0.55)',
backdropFilter: 'blur(20px) saturate(180%)',
WebkitBackdropFilter: 'blur(20px) saturate(180%)',
border: '0.5px solid rgba(0, 0, 0, 0.06)',
boxShadow: '0 4px 14px -6px rgba(0, 0, 0, 0.18), 0 0 0 0.5px rgba(0,0,0,0.04)',
}}
>
<img src="AppIcon.png" alt="" style={{ width: 18, height: 18, borderRadius: 4 }} />
<span>OpenLess 正在启动</span>
</div>
</div>
);
}
2 changes: 1 addition & 1 deletion openless-all/app/src/i18n/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ export const zhCN = {
startStop: '开始 / 停止录音',
cancel: '取消本次录音',
confirm: '胶囊确认插入',
switchStyle: '切换上一次风格',
switchStyle: '切换到上一个风格',
openApp: '打开 OpenLess',
confirmHint: '点击右侧 ✓',
notSupported: '暂未支持',
Expand Down
2 changes: 1 addition & 1 deletion openless-all/app/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ export const zhTW: typeof zhCN = {
startStop: '開始 / 停止錄音',
cancel: '取消本次錄音',
confirm: '膠囊確認插入',
switchStyle: '切換上一次風格',
switchStyle: '切換到上一個風格',
openApp: '打開 OpenLess',
confirmHint: '點擊右側 ✓',
notSupported: '暫未支持',
Expand Down
Loading