From 323130a877cacdbf48d73c22402870367784b65f Mon Sep 17 00:00:00 2001 From: jeffvli Date: Fri, 1 May 2026 21:24:45 -0700 Subject: [PATCH] add toggle for app-suspension for powersave block (#1992) --- src/i18n/locales/en.json | 2 ++ src/main/index.ts | 6 ++-- .../player/hooks/use-power-save-blocker.ts | 22 +++++++++----- .../components/window/window-settings.tsx | 29 ++++++++++++++++++- src/renderer/store/settings.store.ts | 2 ++ 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index f9a9e059b..294078898 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1008,6 +1008,8 @@ "audioFadeOnStatusChange_description": "enables fade out and fade in when play/pause status changes", "preventSleepOnPlayback_description": "prevent the display from sleeping while music is playing", "preventSleepOnPlayback": "prevent sleep on playback", + "preventSuspendOnPlayback_description": "prevent the application from suspending while music is playing", + "preventSuspendOnPlayback": "prevent suspend on playback", "remotePassword_description": "sets the password for the remote control server. These credentials are by default transferred insecurely, so you should use a unique password that you do not care about", "remotePassword": "remote control server password", "remotePort_description": "sets the port for the remote control server", diff --git a/src/main/index.ts b/src/main/index.ts index 97a2bc4a3..350cbfabf 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -931,12 +931,14 @@ ipcMain.on( }, ); -ipcMain.handle('power-save-blocker-start', () => { +ipcMain.handle('power-save-blocker-start', (_event, { full }: { full: boolean }) => { if (powerSaveBlockerId !== null) { return powerSaveBlockerId; } - powerSaveBlockerId = powerSaveBlocker.start('prevent-display-sleep'); + powerSaveBlockerId = powerSaveBlocker.start( + full ? 'prevent-display-sleep' : 'prevent-app-suspension', + ); return powerSaveBlockerId; }); diff --git a/src/renderer/features/player/hooks/use-power-save-blocker.ts b/src/renderer/features/player/hooks/use-power-save-blocker.ts index f797b0136..a7fa0a6fc 100644 --- a/src/renderer/features/player/hooks/use-power-save-blocker.ts +++ b/src/renderer/features/player/hooks/use-power-save-blocker.ts @@ -8,17 +8,17 @@ const ipc = isElectron() ? window.api.ipc : null; export const usePowerSaveBlocker = () => { const status = usePlayerStatus(); - const { preventSleepOnPlayback } = useWindowSettings(); + const { preventSleepOnPlayback, preventSuspendOnPlayback } = useWindowSettings(); const startPowerSaveBlocker = useCallback(async () => { if (!ipc) return; try { - await ipc.invoke('power-save-blocker-start'); + await ipc.invoke('power-save-blocker-start', { full: preventSleepOnPlayback }); } catch (error) { console.error('Failed to start power save blocker:', error); } - }, []); + }, [preventSleepOnPlayback]); const stopPowerSaveBlocker = useCallback(async () => { if (!ipc) return; @@ -31,16 +31,21 @@ export const usePowerSaveBlocker = () => { }, []); useEffect(() => { - if (!preventSleepOnPlayback) return; + if (!preventSleepOnPlayback || !preventSuspendOnPlayback) return; if (status === PlayerStatus.PLAYING) { startPowerSaveBlocker(); } else { stopPowerSaveBlocker(); } - }, [status, preventSleepOnPlayback, startPowerSaveBlocker, stopPowerSaveBlocker]); + }, [ + status, + preventSleepOnPlayback, + startPowerSaveBlocker, + stopPowerSaveBlocker, + preventSuspendOnPlayback, + ]); - // Clean up on unmount useEffect(() => { return () => { stopPowerSaveBlocker(); @@ -56,8 +61,11 @@ const PowerSaveBlockerHookInner = () => { export const PowerSaveBlockerHook = () => { const isElectronEnv = isElectron(); const preventSleepOnPlayback = useSettingsStore((state) => state.window.preventSleepOnPlayback); + const preventSuspendOnPlayback = useSettingsStore( + (state) => state.window.preventSuspendOnPlayback, + ); - if (!isElectronEnv || !preventSleepOnPlayback) { + if (!isElectronEnv || !preventSleepOnPlayback || !preventSuspendOnPlayback) { return null; } diff --git a/src/renderer/features/settings/components/window/window-settings.tsx b/src/renderer/features/settings/components/window/window-settings.tsx index cdfb0923a..c8e729866 100644 --- a/src/renderer/features/settings/components/window/window-settings.tsx +++ b/src/renderer/features/settings/components/window/window-settings.tsx @@ -184,7 +184,7 @@ export const WindowSettings = memo(() => { { if (!e) return; localSettings?.set( @@ -206,6 +206,33 @@ export const WindowSettings = memo(() => { isHidden: !isElectron(), title: t('setting.preventSleepOnPlayback', { postProcess: 'sentenceCase' }), }, + { + control: ( + { + if (!e) return; + localSettings?.set( + 'window_prevent_suspend_on_playback', + e.currentTarget.checked, + ); + setSettings({ + window: { + preventSuspendOnPlayback: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: t('setting.preventSuspendOnPlayback', { + context: 'description', + postProcess: 'sentenceCase', + }), + isHidden: !isElectron(), + title: t('setting.preventSuspendOnPlayback', { postProcess: 'sentenceCase' }), + }, ]; return ( diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index 302a7cf55..95ad35a11 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -638,6 +638,7 @@ const WindowSettingsSchema = z.object({ exitToTray: z.boolean(), minimizeToTray: z.boolean(), preventSleepOnPlayback: z.boolean(), + preventSuspendOnPlayback: z.boolean(), releaseChannel: z.enum(['alpha', 'beta', 'latest']), startMinimized: z.boolean(), tray: z.boolean(), @@ -1914,6 +1915,7 @@ const initialState: SettingsState = { exitToTray: false, minimizeToTray: false, preventSleepOnPlayback: false, + preventSuspendOnPlayback: false, releaseChannel: 'latest', startMinimized: false, tray: true,