fix: clean up GPU flags — hardware H.264 encoding not available on Win/Mac
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.
This commit is contained in:
@@ -522,6 +522,21 @@ function registerIpcHandlers(): void {
|
|||||||
// a safety net to prevent unhandled-message warnings
|
// 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
|
// Auto-launch settings
|
||||||
ipcMain.handle('get-auto-launch-settings', (): { openAtLogin: boolean; startMinimized: boolean } => {
|
ipcMain.handle('get-auto-launch-settings', (): { openAtLogin: boolean; startMinimized: boolean } => {
|
||||||
const saved = loadAutoLaunchSettings();
|
const saved = loadAutoLaunchSettings();
|
||||||
@@ -568,28 +583,45 @@ function initAutoUpdater(): void {
|
|||||||
autoUpdater.autoDownload = true;
|
autoUpdater.autoDownload = true;
|
||||||
autoUpdater.autoInstallOnAppQuit = 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 }) => {
|
autoUpdater.on('update-available', (info: { version: string }) => {
|
||||||
|
updateConfirmed = true;
|
||||||
mainWindow?.webContents.send('update-available', { version: info.version });
|
mainWindow?.webContents.send('update-available', { version: info.version });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
autoUpdater.on('update-not-available', () => {
|
||||||
|
updateConfirmed = false;
|
||||||
|
});
|
||||||
|
|
||||||
autoUpdater.on('update-downloaded', (info: { version: string }) => {
|
autoUpdater.on('update-downloaded', (info: { version: string }) => {
|
||||||
mainWindow?.webContents.send('update-downloaded', { version: info.version });
|
mainWindow?.webContents.send('update-downloaded', { version: info.version });
|
||||||
});
|
});
|
||||||
|
|
||||||
autoUpdater.on('error', (err: Error) => {
|
autoUpdater.on('error', (err: Error) => {
|
||||||
|
// 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', {
|
mainWindow?.webContents.send('update-error', {
|
||||||
message: err.message,
|
message: err.message,
|
||||||
releaseUrl: 'https://github.com/TheZwiss/backspace/releases/latest',
|
releaseUrl: 'https://github.com/TheZwiss/backspace/releases/latest',
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initial check with 10s delay
|
// Initial check with 10s delay
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
updateConfirmed = false;
|
||||||
autoUpdater.checkForUpdates().catch(() => {});
|
autoUpdater.checkForUpdates().catch(() => {});
|
||||||
}, 10_000);
|
}, 10_000);
|
||||||
|
|
||||||
// Periodic check every 4 hours
|
// Periodic check every 4 hours
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
updateConfirmed = false;
|
||||||
autoUpdater.checkForUpdates().catch(() => {});
|
autoUpdater.checkForUpdates().catch(() => {});
|
||||||
}, 4 * 60 * 60 * 1000);
|
}, 4 * 60 * 60 * 1000);
|
||||||
} catch {
|
} 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
|
// 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.
|
// libraries are loaded in the same process. Force GTK 3 for compatibility.
|
||||||
if (process.platform === 'linux') {
|
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
|
// Purge ALL stale caches so Electron always loads fresh code on launch
|
||||||
await session.defaultSession.clearStorageData({ storages: ['serviceworkers'] });
|
await session.defaultSession.clearStorageData({ storages: ['serviceworkers'] });
|
||||||
await session.defaultSession.clearCache();
|
await session.defaultSession.clearCache();
|
||||||
|
|||||||
Reference in New Issue
Block a user