perf(desktop): reduce CPU/GPU overhead in Tauri shell
- SSH monitor: adaptive polling 2s→10s after stabilization, cheap TCP probe before expensive SSH subprocess check - SSH setup: exponential backoff in wait_for_master_ready and wait_local_forward_ready (250ms→2s cap) - Health checks: exponential backoff (100ms→1s / 250ms→2s) instead of flat intervals - Startup recovery poll: cap at 15 retries instead of infinite - Remove webview log target in release builds (eliminates IPC overhead) - Set global NO_PROXY env var at startup for all loopback addresses - Remove reqwest::blocking feature; use raw TCP for sidecar shutdown and SSH health checks - Disable pinch-to-zoom on macOS via WKWebView.setAllowsMagnification - Add WebView2 browser args on Windows (proxy bypass + disable unused UI features) - Add Cargo release profile: thin LTO, codegen-units=1, strip - Extract apply_platform_window_config for consistent window setup - Add vibrancy toggle in Appearance settings (macOS desktop only) with solid background fallback when disabled
This commit is contained in:
@@ -277,6 +277,8 @@ function App({ apis }: AppProps) {
|
||||
if (providersCount > 0 && agentsCount > 0) return;
|
||||
|
||||
let active = true;
|
||||
let retries = 0;
|
||||
const MAX_RETRIES = 15;
|
||||
const attempt = async () => {
|
||||
const state = useConfigStore.getState();
|
||||
if (state.providers.length > 0 && state.agents.length > 0) return;
|
||||
@@ -287,7 +289,11 @@ function App({ apis }: AppProps) {
|
||||
};
|
||||
|
||||
void attempt();
|
||||
const id = setInterval(() => { if (active) void attempt(); }, 2000);
|
||||
const id = setInterval(() => {
|
||||
if (!active) return;
|
||||
if (++retries >= MAX_RETRIES) { clearInterval(id); return; }
|
||||
void attempt();
|
||||
}, 2000);
|
||||
return () => { active = false; clearInterval(id); };
|
||||
}, [isConnected, isVSCodeRuntime, loadAgents, loadProviders, providersCount, agentsCount]);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
import { isDesktopShell, isVSCodeRuntime, isWebRuntime } from '@/lib/desktop';
|
||||
import { isDesktopShell, isVSCodeRuntime, isWebRuntime, desktopSetVibrancy } from '@/lib/desktop';
|
||||
import { useDeviceInfo } from '@/lib/device';
|
||||
import { usePwaDetection } from '@/hooks/usePwaDetection';
|
||||
import { updateDesktopSettings } from '@/lib/persistence';
|
||||
@@ -209,6 +209,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
} = useThemeSystem();
|
||||
|
||||
const [themesReloading, setThemesReloading] = React.useState(false);
|
||||
const [vibrancyEnabled, setVibrancyEnabled] = React.useState(true);
|
||||
const [chatRenderPreviewTick, setChatRenderPreviewTick] = React.useState(0);
|
||||
const reportUsage = useUIStore(state => state.reportUsage);
|
||||
const setReportUsage = useUIStore(state => state.setReportUsage);
|
||||
@@ -219,6 +220,28 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
void updateDesktopSettings({ reportUsage: enabled });
|
||||
}, [setReportUsage]);
|
||||
|
||||
const isMacDesktop = React.useMemo(() => {
|
||||
if (!isDesktopShell()) return false;
|
||||
if (typeof navigator === 'undefined') return false;
|
||||
return /Macintosh|Mac OS X/.test(navigator.userAgent || '');
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!isMacDesktop) return;
|
||||
const stored = localStorage.getItem('desktopVibrancy');
|
||||
if (stored !== null) {
|
||||
setVibrancyEnabled(stored !== 'false');
|
||||
}
|
||||
}, [isMacDesktop]);
|
||||
|
||||
const handleVibrancyChange = React.useCallback((enabled: boolean) => {
|
||||
setVibrancyEnabled(enabled);
|
||||
localStorage.setItem('desktopVibrancy', String(enabled));
|
||||
document.documentElement.classList.toggle('no-vibrancy', !enabled);
|
||||
void desktopSetVibrancy(enabled);
|
||||
void updateDesktopSettings({ desktopVibrancy: enabled });
|
||||
}, []);
|
||||
|
||||
const shouldAnimateChatPreview = isSettingsDialogOpen
|
||||
&& (visibleSettings ? visibleSettings.includes('chatRenderMode') : true);
|
||||
|
||||
@@ -503,6 +526,24 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
{isMacDesktop && (
|
||||
<div className="flex items-center gap-2 py-1.5">
|
||||
<Checkbox
|
||||
checked={vibrancyEnabled}
|
||||
onChange={handleVibrancyChange}
|
||||
ariaLabel="Toggle window vibrancy"
|
||||
/>
|
||||
<div className="flex min-w-0 flex-col">
|
||||
<span className="typography-ui-label text-foreground">
|
||||
Window vibrancy
|
||||
</span>
|
||||
<span className="typography-meta text-muted-foreground">
|
||||
Translucent window background. Disabling may reduce energy usage.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showPwaInstallNameSetting && (
|
||||
<div className="py-1.5 space-y-1.5">
|
||||
<div className="flex min-w-0 flex-col">
|
||||
|
||||
@@ -147,6 +147,8 @@ export type DesktopSettings = {
|
||||
skillCatalogs?: SkillCatalogConfig[];
|
||||
// Opt-in to send anonymous usage reports for update checks (default: true)
|
||||
reportUsage?: boolean;
|
||||
// macOS window vibrancy effect (default: true)
|
||||
desktopVibrancy?: boolean;
|
||||
};
|
||||
|
||||
type TauriGlobal = {
|
||||
@@ -637,3 +639,18 @@ export const clearDesktopCache = async (): Promise<boolean> => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const desktopSetVibrancy = async (enabled: boolean): Promise<boolean> => {
|
||||
if (!isTauriShell()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const tauri = (window as unknown as { __TAURI__?: TauriGlobal }).__TAURI__;
|
||||
await tauri?.core?.invoke?.('desktop_set_vibrancy', { enabled });
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('Failed to set vibrancy', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,6 +52,10 @@ const setRootDeviceAttributes = (
|
||||
|
||||
if (isTauriShellRuntime) {
|
||||
root.classList.add('desktop-runtime');
|
||||
// Apply no-vibrancy class early so the first paint uses a solid background
|
||||
// when vibrancy was previously disabled by the user.
|
||||
const vibrancyOff = localStorage.getItem('desktopVibrancy') === 'false';
|
||||
root.classList.toggle('no-vibrancy', vibrancyOff);
|
||||
root.style.setProperty('--is-mobile', '0');
|
||||
root.style.setProperty('--device-type', 'desktop');
|
||||
root.style.setProperty('--font-scale', '1');
|
||||
|
||||
@@ -82,6 +82,9 @@ const persistToLocalStorage = (settings: DesktopSettings) => {
|
||||
localStorage.removeItem('openchamber.pwaName');
|
||||
}
|
||||
}
|
||||
if (typeof settings.desktopVibrancy === 'boolean') {
|
||||
localStorage.setItem('desktopVibrancy', String(settings.desktopVibrancy));
|
||||
}
|
||||
};
|
||||
|
||||
type PersistApi = {
|
||||
|
||||
@@ -135,12 +135,29 @@
|
||||
overscroll-behavior-y: none;
|
||||
}
|
||||
|
||||
:root.desktop-runtime body,
|
||||
:root.desktop-runtime #root {
|
||||
:root.desktop-runtime:not(.no-vibrancy) body,
|
||||
:root.desktop-runtime:not(.no-vibrancy) #root {
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
:root.desktop-runtime.no-vibrancy body,
|
||||
:root.desktop-runtime.no-vibrancy #root {
|
||||
background: var(--background) !important;
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
/* When vibrancy is off, force sidebar overlays to solid and disable blur. */
|
||||
:root.desktop-runtime.no-vibrancy {
|
||||
--sidebar-overlay-strong: var(--sidebar) !important;
|
||||
--sidebar-overlay-soft: var(--sidebar) !important;
|
||||
}
|
||||
|
||||
:root.desktop-runtime.no-vibrancy .backdrop-blur {
|
||||
-webkit-backdrop-filter: none !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
||||
.font-sans {
|
||||
font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif) !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user