diff --git a/openless-all/app/src-tauri/src/commands.rs b/openless-all/app/src-tauri/src/commands.rs index 79a8f5b4..1ed9af5e 100644 --- a/openless-all/app/src-tauri/src/commands.rs +++ b/openless-all/app/src-tauri/src/commands.rs @@ -3564,12 +3564,6 @@ pub async fn github_device_flow_poll( Ok(GithubDevicePollResult::Error { message: msg }) } -#[tauri::command] -pub fn is_no_compositing_mode() -> bool { - // Linux WebKitGTK: WEBKIT_DISABLE_COMPOSITING_MODE=1 时 backdrop-filter 不可用 - std::env::var("WEBKIT_DISABLE_COMPOSITING_MODE").as_deref() == Ok("1") -} - #[cfg(test)] mod tests { use super::{ diff --git a/openless-all/app/src-tauri/src/lib.rs b/openless-all/app/src-tauri/src/lib.rs index 4b65b3d8..3f1d8d19 100644 --- a/openless-all/app/src-tauri/src/lib.rs +++ b/openless-all/app/src-tauri/src/lib.rs @@ -471,7 +471,6 @@ pub fn run() { #[cfg(target_os = "windows")] commands::sherpa_onnx_asr_reveal_model_dir, commands::export_error_log, - commands::is_no_compositing_mode, restart_app, ]) .build(tauri::generate_context!()) diff --git a/openless-all/app/src-tauri/tauri.linux.conf.json b/openless-all/app/src-tauri/tauri.linux.conf.json index 36b93619..abbd83b9 100644 --- a/openless-all/app/src-tauri/tauri.linux.conf.json +++ b/openless-all/app/src-tauri/tauri.linux.conf.json @@ -11,7 +11,7 @@ "minHeight": 640, "resizable": true, "decorations": false, - "transparent": true, + "transparent": false, "shadow": true, "visible": false, "acceptFirstMouse": true @@ -23,7 +23,7 @@ "width": 220, "height": 110, "decorations": false, - "transparent": true, + "transparent": false, "shadow": false, "alwaysOnTop": true, "skipTaskbar": true, @@ -40,7 +40,7 @@ "width": 380, "height": 440, "decorations": false, - "transparent": true, + "transparent": false, "shadow": true, "alwaysOnTop": true, "skipTaskbar": true, diff --git a/openless-all/app/src/App.tsx b/openless-all/app/src/App.tsx index 5071bffc..fcf37228 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'; import { APP_THEME_KEY, applyAppTheme, readAppTheme } from './lib/appTheme'; @@ -180,18 +179,6 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) { }; }, [os]); - // Linux: 检测 WEBKIT_DISABLE_COMPOSITING_MODE → 触发磨砂 fallback(#570, #553) - 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); - }); - }, []); - return ( {gate === 'onboarding' ? setGate('ready')} /> : } @@ -199,4 +186,3 @@ export function App({ isCapsule, isQa, forcedOs }: AppProps) { ); } - diff --git a/openless-all/app/src/components/Capsule.tsx b/openless-all/app/src/components/Capsule.tsx index 48065a57..eb4afcb4 100644 --- a/openless-all/app/src/components/Capsule.tsx +++ b/openless-all/app/src/components/Capsule.tsx @@ -247,7 +247,7 @@ function Pill({ os, state, level, insertedChars, message, onCancel, onConfirm }: const shadowAlpha = 0.20 + ambient * 0.10; return ( - // 假毛玻璃:半透明白底 + .ol-frost 噪点纹理 + 内描边高光 + 柔和阴影。 + // 非 Linux 走假毛玻璃;Linux 禁用透明窗口后由 .ol-frost 平台规则退成不透明面。 // 不写 backdrop-filter —— webview 模糊不了透明窗口背后的桌面(Tauri 上游限制)。
- {/* Main content — v1.3.1-8 用户希望"sidebar / main panel / caption 三处玻璃统一"。 - 从 var(--ol-surface) 不透明白底 改成半透明白 + backdrop-filter,跟 sidebar - 一起坐在 WindowChrome 的磨砂底板上,整体一块连续玻璃。 */} + {/* Main content — Linux 禁用透明窗口后使用不透明面;其他平台保留玻璃层。 */}
); } - diff --git a/openless-all/app/src/components/WindowChrome.tsx b/openless-all/app/src/components/WindowChrome.tsx index ab5b1079..e7068354 100644 --- a/openless-all/app/src/components/WindowChrome.tsx +++ b/openless-all/app/src/components/WindowChrome.tsx @@ -37,7 +37,7 @@ export function WindowChrome({ const consoleRadius = os === 'mac' ? 20 : os === 'win' ? WIN_CONSOLE_RADIUS : 14; const titlebarHeight = os === 'mac' ? MAC_TITLEBAR_HEIGHT : os === 'linux' ? LINUX_TITLEBAR_HEIGHT : 0; - // 三个平台共用半透明玻璃 background + backdropFilter。 + // macOS / Windows 共用半透明玻璃 background + backdropFilter。 // macOS: NSVisualEffectView 提供材质;Windows: Tauri apply_mica 提供 Mica; // Linux: decorations:false 后 CSS 磨砂玻璃自成背景。 // diff --git a/openless-all/app/src/main.tsx b/openless-all/app/src/main.tsx index 0de8f9fd..f9b9d8b7 100644 --- a/openless-all/app/src/main.tsx +++ b/openless-all/app/src/main.tsx @@ -1,6 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { App } from "./App"; +import { detectOS } from "./components/WindowChrome"; import i18n from "./i18n"; // 副作用:触发 i18next init import { applyAppTheme, readAppTheme } from "./lib/appTheme"; import "./styles/tokens.css"; @@ -13,6 +14,8 @@ const windowKind = params.get("window"); const isCapsule = windowKind === "capsule"; const isQa = windowKind === "qa"; const osQuery = params.get("os") as OS | null; +const os = osQuery ?? detectOS(); +document.documentElement.dataset.olPlatform = os; applyAppTheme(readAppTheme()); @@ -21,7 +24,7 @@ const root = ReactDOM.createRoot(document.getElementById("root")!); const renderApp = () => { root.render( - + , ); }; diff --git a/openless-all/app/src/pages/QaPanel.tsx b/openless-all/app/src/pages/QaPanel.tsx index 20b1367f..184e2fc3 100644 --- a/openless-all/app/src/pages/QaPanel.tsx +++ b/openless-all/app/src/pages/QaPanel.tsx @@ -611,9 +611,8 @@ function truncate(text: string, max: number): string { // ── 样式 ────────────────────────────────────────────────────────────── -// 假毛玻璃外壳:玻璃质感(体渐变 + 高光扫面 + 噪点颗粒)全部由 .ol-frost 提供; -// 这里只管布局 + 内描边高光 + 柔和阴影。webview 模糊不了透明窗口背后的桌面 -// (Tauri 上游限制),所以不写 background / backdrop-filter。 +// 非 Linux 走 .ol-frost 假毛玻璃;Linux 禁用透明窗口后退成不透明面。 +// 这里只管布局 + 内描边高光 + 柔和阴影,所以不写 background / backdrop-filter。 const shellStyle: CSSProperties = { width: '100%', height: '100vh', diff --git a/openless-all/app/src/styles/global.css b/openless-all/app/src/styles/global.css index 9f75a28d..a52a9d49 100644 --- a/openless-all/app/src/styles/global.css +++ b/openless-all/app/src/styles/global.css @@ -7,6 +7,12 @@ html, body, #root { overflow: hidden; } +html[data-ol-platform="linux"], +html[data-ol-platform="linux"] body, +html[data-ol-platform="linux"] #root { + background: var(--ol-surface); +} + body { user-select: none; -webkit-user-select: none; @@ -151,7 +157,7 @@ a { color: inherit; text-decoration: none; } 是 Tauri 已知的上游限制(issue #2827 / #10064 / #6876)。所以这里**不做 真实高斯模糊**:宿主元素保留半透明白底,这层 ::before 叠一张细颗粒噪点纹理 (磨砂质感来源);内描边高光与柔和阴影由宿主自带的 box-shadow 提供。 - 纯静态 CSS,零运行时 / 动画开销,macOS / Windows / Linux 像素一致。 + 纯静态 CSS,零运行时 / 动画开销。Linux 主动禁用透明窗口后走纯不透明面。 宿主元素自带 border-radius 即可,::before 噪点层 inherit 圆角;宿主不要再设 backdrop-filter(死代码)。 */ .ol-frost { @@ -182,52 +188,10 @@ a { color: inherit; text-decoration: none; } pointer-events: none; } -/* ── Linux no-compositing fallback ────────────────────────────────────── - WEBKIT_DISABLE_COMPOSITING_MODE=1 时 backdrop-filter 不可用,用噪点纹理 - 替代磨砂效果。data-ol-no-compositing 由 App.tsx 在初始化时设置。 - - !important 是因为三处目标的 backdrop-filter / background 均为 inline style - (WindowChrome.tsx / FloatingShell.tsx 的 style={...}),CSS class 必须 - 用 !important 才能覆盖。 */ - -[data-ol-no-compositing] .ol-winchrome { - position: relative; - isolation: isolate; - /* !important 覆盖 WindowChrome.tsx inline backdropFilter */ - backdrop-filter: none !important; - -webkit-backdrop-filter: none !important; - /* 提高透明梯度不透明度,补偿缺少模糊的视觉深度 - 注意:此三层的渐变参数与 WindowChrome.tsx 的 inline background 同步, - 改动那边时请同步更新这里。 */ - background: - radial-gradient(120% 80% at 0% 0%, rgba(255,255,255,0.55) 0%, rgba(255,255,255,0) 60%), - radial-gradient(100% 70% at 100% 100%, rgba(37,99,235,0.07) 0%, rgba(37,99,235,0) 55%), - linear-gradient(180deg, rgba(245,245,247,0.96) 0%, rgba(232,232,236,0.96) 100%) !important; +html[data-ol-platform="linux"] .ol-frost { + background: var(--ol-surface); } -[data-ol-no-compositing] .ol-winchrome::after { - content: ''; - position: absolute; - inset: 0; - z-index: -1; - border-radius: inherit; - /* 灰阶噪点颗粒,低 opacity 模拟磨砂质感 */ - background-image: var(--ol-frost-grain); - background-size: 100px 100px; - opacity: 0.20; - pointer-events: none; -} - -[data-ol-no-compositing] .ol-console-main { - /* !important 覆盖 FloatingShell.tsx inline backdropFilter */ - backdrop-filter: none !important; - -webkit-backdrop-filter: none !important; - background: rgba(255, 255, 255, 0.80) !important; -} - -[data-ol-no-compositing] .ol-linux-titlebar { - /* !important 覆盖 WindowChrome.tsx LinuxTitlebar inline backdropFilter */ - backdrop-filter: none !important; - -webkit-backdrop-filter: none !important; - background: rgba(245, 245, 247, 0.95) !important; +html[data-ol-platform="linux"] .ol-frost::before { + content: none; }