diff --git a/electron/main/index.ts b/electron/main/index.ts index 4ded0f091..e9d86e8c2 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -17,13 +17,21 @@ import { ClawHubService } from '../gateway/clawhub'; import { ensureClawXContext, repairClawXOnlyBootstrapFiles } from '../utils/openclaw-workspace'; import { isQuitting, setQuitting } from './app-state'; -// Disable GPU acceleration only on Linux where GPU driver issues are common. -// On Windows and macOS, hardware acceleration is essential for responsive UI; -// forcing CPU rendering makes the main thread compete with sync I/O and -// contributes to "Not Responding" hangs. -if (process.platform === 'linux') { - app.disableHardwareAcceleration(); -} +// Disable GPU hardware acceleration globally for maximum stability across +// all GPU configurations (no GPU, integrated, discrete). +// +// Rationale (following VS Code's philosophy): +// - Page/file loading is async data fetching — zero GPU dependency. +// - The original per-platform GPU branching was added to avoid CPU rendering +// competing with sync I/O on Windows, but all file I/O is now async +// (fs/promises), so that concern no longer applies. +// - Software rendering is deterministic across all hardware; GPU compositing +// behaviour varies between vendors (Intel, AMD, NVIDIA, Apple Silicon) and +// driver versions, making it the #1 source of rendering bugs in Electron. +// +// Users who want GPU acceleration can pass `--enable-gpu` on the CLI or +// set `"disable-hardware-acceleration": false` in the app config (future). +app.disableHardwareAcceleration(); // Global references let mainWindow: BrowserWindow | null = null; diff --git a/src/pages/Chat/index.tsx b/src/pages/Chat/index.tsx index 8e976dead..4874a36ad 100644 --- a/src/pages/Chat/index.tsx +++ b/src/pages/Chat/index.tsx @@ -38,14 +38,19 @@ export function Chat() { const messagesEndRef = useRef(null); const [streamingTimestamp, setStreamingTimestamp] = useState(0); - // Load data when gateway is running + // Load data when gateway is running. + // When the store already holds messages for this session (i.e. the user + // is navigating *back* to Chat), use quiet mode so the existing messages + // stay visible while fresh data loads in the background. This avoids + // an unnecessary messages → spinner → messages flicker. useEffect(() => { if (!isGatewayRunning) return; let cancelled = false; + const hasExistingMessages = useChatStore.getState().messages.length > 0; (async () => { await loadSessions(); if (cancelled) return; - await loadHistory(); + await loadHistory(hasExistingMessages); })(); return () => { cancelled = true;