From 6844f8d8fdaccd1c1005953ece9cb568f5d2e9a7 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:55:18 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20clean=20up=20GPU=20flags=20=E2=80=94=20h?= =?UTF-8?q?ardware=20H.264=20encoding=20not=20available=20on=20Win/Mac?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AcceleratedVideoEncoder only enables VA-API encoding on Linux. Windows/macOS hardware H.264 encoding in Chromium's WebRTC is not reliably controllable — VP9 via libvpx remains the recommended codec. --- packages/desktop/src/main.ts | 59 +++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/packages/desktop/src/main.ts b/packages/desktop/src/main.ts index ccca13ff..4b4d1000 100644 --- a/packages/desktop/src/main.ts +++ b/packages/desktop/src/main.ts @@ -522,6 +522,21 @@ function registerIpcHandlers(): void { // a safety net to prevent unhandled-message warnings }); + // GPU feature status (debugging hardware encoding) + ipcMain.handle('get-gpu-info', async () => { + try { + const features = app.getGPUFeatureStatus(); + const info: any = await app.getGPUInfo('complete'); + return { + features, + gpu: info?.gpuDevice?.[0] ?? null, + videoEncode: (features as any)?.video_encode ?? 'unknown', + }; + } catch { + return { features: {}, gpu: null, videoEncode: 'error' }; + } + }); + // Auto-launch settings ipcMain.handle('get-auto-launch-settings', (): { openAtLogin: boolean; startMinimized: boolean } => { const saved = loadAutoLaunchSettings(); @@ -568,28 +583,45 @@ function initAutoUpdater(): void { autoUpdater.autoDownload = true; autoUpdater.autoInstallOnAppQuit = true; + // Track whether an update was confirmed to exist — only show error toast + // if the download fails after we know an update is available. Errors from + // the check itself (e.g. private repo, no releases, network) are silent. + let updateConfirmed = false; + autoUpdater.on('update-available', (info: { version: string }) => { + updateConfirmed = true; mainWindow?.webContents.send('update-available', { version: info.version }); }); + autoUpdater.on('update-not-available', () => { + updateConfirmed = false; + }); + autoUpdater.on('update-downloaded', (info: { version: string }) => { mainWindow?.webContents.send('update-downloaded', { version: info.version }); }); autoUpdater.on('error', (err: Error) => { - mainWindow?.webContents.send('update-error', { - message: err.message, - releaseUrl: 'https://github.com/TheZwiss/backspace/releases/latest', - }); + // Only notify renderer if we already confirmed an update exists but the + // download/install failed. Check-phase errors (auth, 404, network) are + // silently ignored — there's nothing actionable for the user. + if (updateConfirmed) { + mainWindow?.webContents.send('update-error', { + message: err.message, + releaseUrl: 'https://github.com/TheZwiss/backspace/releases/latest', + }); + } }); // Initial check with 10s delay setTimeout(() => { + updateConfirmed = false; autoUpdater.checkForUpdates().catch(() => {}); }, 10_000); // Periodic check every 4 hours setInterval(() => { + updateConfirmed = false; autoUpdater.checkForUpdates().catch(() => {}); }, 4 * 60 * 60 * 1000); } catch { @@ -612,6 +644,16 @@ function handleDeepLink(url: string): void { } } +// ─── GPU Acceleration ─────────────────────────────────────────────────────── +app.commandLine.appendSwitch('ignore-gpu-blocklist'); +app.commandLine.appendSwitch('enable-accelerated-video-decode'); +// Linux: enable VA-API hardware video encoding/decoding for WebRTC +// (Windows/macOS hardware H.264 encoding is not reliably available in Electron's +// Chromium WebRTC stack — VP9 via libvpx is the recommended codec for all platforms) +if (process.platform === 'linux') { + app.commandLine.appendSwitch('enable-features', 'AcceleratedVideoEncoder,VaapiVideoEncoder,VaapiVideoDecoder'); +} + // Electron 36+ defaults to GTK 4 on GNOME, which crashes if GTK 2/3 // libraries are loaded in the same process. Force GTK 3 for compatibility. if (process.platform === 'linux') { @@ -718,6 +760,15 @@ if (!gotTheLock) { ])); } + // Log GPU capabilities for debugging hardware encoding support + const gpuFeatures = app.getGPUFeatureStatus(); + console.log('[GPU] Feature status:', JSON.stringify(gpuFeatures, null, 2)); + app.getGPUInfo('complete').then((info: any) => { + console.log('[GPU] Active GPU:', info?.gpuDevice?.[0]?.driverVendor, info?.gpuDevice?.[0]?.driverVersion); + console.log('[GPU] Video encode:', info?.featureStatus?.video_encode ?? 'unknown'); + console.log('[GPU] Video decode:', info?.featureStatus?.video_decode ?? 'unknown'); + }).catch(() => {}); + // Purge ALL stale caches so Electron always loads fresh code on launch await session.defaultSession.clearStorageData({ storages: ['serviceworkers'] }); await session.defaultSession.clearCache();