Skip to content

Commit 8b21551

Browse files
committed
feat(desktop): add prevent-sleep settings toggle
The desktop app unconditionally started a powerSaveBlocker at launch with no user-facing way to opt out. Add a "Prevent system sleep" switch under a new Power section in General settings (desktop only). - main: persist preventSleep in the settings store; default stays enabled (only explicit false opts out) so existing installs keep the historical always-on behavior; set-prevent-sleep IPC starts/stops the blocker live and broadcasts to all windows - preload/renderer/app: bridge get/setPreventSleepEnabled through the platform context, mirroring the pinchZoom pattern - i18n: translate the new section and row across all 18 locales - tests: unit-cover the persisted-setting resolution (Electron-free, same split as close-to-tray); add prevent-sleep-smoke, a Playwright-driven dynamic test that clicks the real Settings switch and asserts macOS pmset NoIdleSleepAssertion across default-on, disable, relaunch persistence, and re-enable - ci: run the smoke in a new desktop-smoke (macos) job in test.yml Signed-off-by: thomas-yanga <odie_majere@outlook.com>
1 parent 0a7f145 commit 8b21551

32 files changed

Lines changed: 309 additions & 3 deletions

File tree

.github/workflows/test.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,38 @@ jobs:
9696
retention-days: 7
9797
path: packages/*/.artifacts/unit/junit.xml
9898

99+
desktop-smoke:
100+
name: desktop-smoke (macos)
101+
# The prevent-sleep smoke drives the real packaged main bundle through Playwright and asserts
102+
# against pmset, so it needs a macOS runner with a window server; keep it out of the unit matrix.
103+
runs-on: macos-14
104+
defaults:
105+
run:
106+
shell: bash
107+
steps:
108+
- name: Checkout repository
109+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
110+
with:
111+
token: ${{ secrets.GITHUB_TOKEN }}
112+
113+
- name: Setup Node
114+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
115+
with:
116+
node-version: "24"
117+
118+
- name: Setup Bun
119+
uses: ./.github/actions/setup-bun
120+
121+
- name: Build desktop main bundle
122+
working-directory: packages/desktop
123+
run: bun run build
124+
timeout-minutes: 15
125+
126+
- name: Run prevent-sleep smoke
127+
working-directory: packages/desktop
128+
run: bun run test:prevent-sleep-smoke
129+
timeout-minutes: 10
130+
99131
e2e:
100132
name: e2e (${{ matrix.settings.name }})
101133
strategy:

packages/app/src/components/settings-v2/general.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ export const SettingsGeneralV2: Component = () => {
132132
{ initialValue: false },
133133
)
134134

135+
const [preventSleep, { mutate: setPreventSleep }] = createResource(
136+
() => (desktop() && platform.getPreventSleepEnabled ? true : false),
137+
() => Promise.resolve(platform.getPreventSleepEnabled?.() ?? true).catch(() => true),
138+
{ initialValue: true },
139+
)
140+
135141
onMount(() => {
136142
void theme.loadThemes()
137143
})
@@ -252,6 +258,13 @@ export const SettingsGeneralV2: Component = () => {
252258
void update.catch(() => setPinchZoom(!checked))
253259
}
254260

261+
const onPreventSleepChange = (checked: boolean) => {
262+
setPreventSleep(checked)
263+
const update = platform.setPreventSleepEnabled?.(checked)
264+
if (!update) return
265+
void update.catch(() => setPreventSleep(!checked))
266+
}
267+
255268
const colorSchemeOptions = createMemo((): { value: ColorScheme; label: string }[] => [
256269
{ value: "system", label: language.t("theme.scheme.system") },
257270
{ value: "light", label: language.t("theme.scheme.light") },
@@ -915,6 +928,25 @@ export const SettingsGeneralV2: Component = () => {
915928
</Show>
916929
)
917930

931+
const PowerSection = () => (
932+
<Show when={desktop()}>
933+
<div class="settings-v2-section">
934+
<h3 class="settings-v2-section-title">{language.t("settings.general.section.power")}</h3>
935+
936+
<SettingsListV2>
937+
<SettingsRowV2
938+
title={language.t("settings.general.row.preventSleep.title")}
939+
description={language.t("settings.general.row.preventSleep.description")}
940+
>
941+
<div data-action="settings-prevent-sleep">
942+
<Switch checked={preventSleep.latest} onChange={onPreventSleepChange} />
943+
</div>
944+
</SettingsRowV2>
945+
</SettingsListV2>
946+
</div>
947+
</Show>
948+
)
949+
918950
return (
919951
<>
920952
<div class="settings-v2-tab-header">
@@ -940,6 +972,8 @@ export const SettingsGeneralV2: Component = () => {
940972

941973
<DisplaySection />
942974

975+
<PowerSection />
976+
943977
<ImportSection />
944978
</div>
945979
</>

packages/app/src/context/platform.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ type PlatformBase = {
122122
/** Allow native pinch/Ctrl-scroll zoom gestures (desktop only) */
123123
setPinchZoomEnabled?(enabled: boolean): Promise<void> | void
124124

125+
/** Get whether the app keeps the system awake while running (desktop only) */
126+
getPreventSleepEnabled?(): Promise<boolean> | boolean
127+
128+
/** Keep the system awake while the app is running (desktop only) */
129+
setPreventSleepEnabled?(enabled: boolean): Promise<void> | void
130+
125131
/** Run a desktop-only menu action from the app chrome */
126132
runDesktopMenuAction?(action: DesktopMenuAction): Promise<void> | void
127133

packages/app/src/i18n/ar.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ export const dict = {
560560
"settings.general.row.expertPanelDefault.title": "تفعيل لجنة الخبراء افتراضيًا",
561561
"settings.general.row.expertPanelDefault.description": "بدء المحادثات الجديدة مع تفعيل لجنة الخبراء، بحيث يبدأ زرها مراجعة السياق الحالي عند الطلب.",
562562
"settings.general.section.display": "شاشة العرض",
563+
"settings.general.section.power": "الطاقة",
563564
"settings.general.row.language.title": "اللغة",
564565
"settings.general.row.language.description": "تغيير لغة العرض لـ DeepAgent Code",
565566
"settings.general.row.appearance.title": "المظهر",
@@ -930,6 +931,8 @@ export const dict = {
930931
"تفعيل التخطيط والصفحة الرئيسية والمحرر وواجهة الجلسة المعاد تصميمها",
931932
"settings.general.row.pinchZoom.title": "التكبير بالقرص",
932933
"settings.general.row.pinchZoom.description": "السماح بإيماءات قرص لوحة اللمس و Ctrl-تمرير للتكبير",
934+
"settings.general.row.preventSleep.title": "منع سكون النظام",
935+
"settings.general.row.preventSleep.description": "إبقاء النظام مستيقظًا أثناء تشغيل التطبيق؛ ويمكن أن تنطفئ الشاشة",
933936
"settings.general.row.zoom.title": "Zoom level",
934937
"settings.general.row.zoom.description": "Set the interface zoom level",
935938
"settings.updates.action.downloading": "جار التنزيل...",

packages/app/src/i18n/br.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ export const dict = {
567567
"settings.general.row.expertPanelDefault.title": "Ativar painel de especialistas por padrão",
568568
"settings.general.row.expertPanelDefault.description": "Iniciar novas conversas com o painel de especialistas ativado, para que seu botão inicie uma revisão do contexto atual sob demanda.",
569569
"settings.general.section.display": "Tela",
570+
"settings.general.section.power": "Energia",
570571
"settings.general.row.language.title": "Idioma",
571572
"settings.general.row.language.description": "Alterar o idioma de exibição do DeepAgent Code",
572573
"settings.general.row.appearance.title": "Aparência",
@@ -954,6 +955,8 @@ export const dict = {
954955
"settings.general.row.pinchZoom.title": "Pinçar para zoom",
955956
"settings.general.row.pinchZoom.description":
956957
"Permitir gestos de pellizco en trackpad y Ctrl-desplazamiento para ampliar",
958+
"settings.general.row.preventSleep.title": "Impedir suspensão do sistema",
959+
"settings.general.row.preventSleep.description": "Manter o sistema ativo enquanto o app está em execução; a tela ainda pode desligar",
957960
"settings.general.row.zoom.title": "Zoom level",
958961
"settings.general.row.zoom.description": "Set the interface zoom level",
959962
"settings.updates.action.downloading": "Baixando...",

packages/app/src/i18n/bs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ export const dict = {
632632
"settings.general.row.expertPanelDefault.title": "Zadano uključi ekspertni panel",
633633
"settings.general.row.expertPanelDefault.description": "Pokreni nove razgovore s uključenim ekspertnim panelom, tako da njegovo dugme po potrebi pokreće pregled trenutnog konteksta.",
634634
"settings.general.section.display": "Prikaz",
635+
"settings.general.section.power": "Napajanje",
635636

636637
"settings.general.row.language.title": "Jezik",
637638
"settings.general.row.language.description": "Promijeni jezik prikaza u DeepAgent Code-u",
@@ -1027,6 +1028,8 @@ export const dict = {
10271028
"settings.general.row.pinchZoom.title": "Powiększanie gestem szczypania",
10281029
"settings.general.row.pinchZoom.description":
10291030
"Zezwól na powiększanie gestem szczypania na trackpadzie i Ctrl-przewijaniem",
1031+
"settings.general.row.preventSleep.title": "Spriječi mirovanje sistema",
1032+
"settings.general.row.preventSleep.description": "Zadržava sistem budnim dok je aplikacija pokrenuta; ekran se i dalje može ugasiti",
10301033
"settings.general.row.zoom.title": "Zoom level",
10311034
"settings.general.row.zoom.description": "Set the interface zoom level",
10321035
"settings.updates.action.downloading": "Preuzimanje...",

packages/app/src/i18n/da.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ export const dict = {
627627
"settings.general.row.expertPanelDefault.title": "Aktivér ekspertpanel som standard",
628628
"settings.general.row.expertPanelDefault.description": "Start nye samtaler med ekspertpanelet aktiveret, så knappen kan gennemgå den aktuelle kontekst efter behov.",
629629
"settings.general.section.display": "Skærm",
630+
"settings.general.section.power": "Strøm",
630631

631632
"settings.general.row.language.title": "Sprog",
632633
"settings.general.row.language.description": "Ændr visningssproget for DeepAgent Code",
@@ -1016,6 +1017,8 @@ export const dict = {
10161017
"settings.general.row.newLayoutDesigns.description": "Aktivér det redesignede layout, hjem, composer og sessions-UI",
10171018
"settings.general.row.pinchZoom.title": "Knib for at zoome",
10181019
"settings.general.row.pinchZoom.description": "Tillad trackpad-knib og Ctrl-scroll til zoom",
1020+
"settings.general.row.preventSleep.title": "Forhindr dvale",
1021+
"settings.general.row.preventSleep.description": "Hold systemet vågent, mens appen kører; skærmen kan stadig slukkes",
10191022
"settings.general.row.zoom.title": "Zoom level",
10201023
"settings.general.row.zoom.description": "Set the interface zoom level",
10211024
"settings.updates.action.downloading": "Downloader...",

packages/app/src/i18n/de.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ export const dict = {
576576
"settings.general.row.expertPanelDefault.title": "Expertengremium standardmäßig aktivieren",
577577
"settings.general.row.expertPanelDefault.description": "Neue Unterhaltungen mit aktiviertem Expertengremium starten, damit dessen Schaltfläche den aktuellen Kontext bei Bedarf prüft.",
578578
"settings.general.section.display": "Anzeige",
579+
"settings.general.section.power": "Energie",
579580
"settings.general.row.language.title": "Sprache",
580581
"settings.general.row.language.description": "Die Anzeigesprache für DeepAgent Code ändern",
581582
"settings.general.row.appearance.title": "Erscheinungsbild",
@@ -961,6 +962,8 @@ export const dict = {
961962
"Überarbeitetes Layout, Startseite, Composer und Sitzungs-UI aktivieren",
962963
"settings.general.row.pinchZoom.title": "Zum Zoomen kneifen",
963964
"settings.general.row.pinchZoom.description": "Trackpad-Kneifen und Strg-Scrollen zum Zoomen erlauben",
965+
"settings.general.row.preventSleep.title": "Ruhezustand des Systems verhindern",
966+
"settings.general.row.preventSleep.description": "Hält das System wach, solange die App läuft; der Bildschirm kann sich weiterhin ausschalten",
964967
"settings.general.row.zoom.title": "Zoom level",
965968
"settings.general.row.zoom.description": "Set the interface zoom level",
966969
"settings.updates.action.downloading": "Wird heruntergeladen...",

packages/app/src/i18n/en.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ export const dict = {
12041204
"settings.general.section.sounds": "Sound effects",
12051205
"settings.general.section.feed": "Feed",
12061206
"settings.general.section.display": "Display",
1207+
"settings.general.section.power": "Power",
12071208
"settings.general.section.sharing": "Sharing",
12081209

12091210
"settings.general.row.language.title": "Language",
@@ -1367,6 +1368,8 @@ export const dict = {
13671368
"settings.general.row.newLayoutDesigns.description": "Enable the redesigned layout, home, composer, and session UI",
13681369
"settings.general.row.pinchZoom.title": "Pinch to zoom",
13691370
"settings.general.row.pinchZoom.description": "Allow trackpad pinch and Ctrl-scroll gestures to zoom",
1371+
"settings.general.row.preventSleep.title": "Prevent system sleep",
1372+
"settings.general.row.preventSleep.description": "Keep the system awake while the app is running; the display can still turn off",
13701373
"settings.general.row.zoom.title": "Zoom level",
13711374
"settings.general.row.zoom.description": "Set the interface zoom level",
13721375

packages/app/src/i18n/es.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ export const dict = {
635635
"settings.general.row.expertPanelDefault.title": "Activar el panel de expertos por defecto",
636636
"settings.general.row.expertPanelDefault.description": "Iniciar nuevas conversaciones con el panel de expertos activado, para que su botón revise el contexto actual cuando se solicite.",
637637
"settings.general.section.display": "Pantalla",
638+
"settings.general.section.power": "Energía",
638639

639640
"settings.general.row.language.title": "Idioma",
640641
"settings.general.row.language.description": "Cambiar el idioma de visualización para DeepAgent Code",
@@ -1037,6 +1038,8 @@ export const dict = {
10371038
"settings.general.row.pinchZoom.title": "Pellizcar para ampliar",
10381039
"settings.general.row.pinchZoom.description":
10391040
"Permitir gestos de pellizco en trackpad y Ctrl-desplazamiento para ampliar",
1041+
"settings.general.row.preventSleep.title": "Evitar la suspensión del sistema",
1042+
"settings.general.row.preventSleep.description": "Mantener el sistema activo mientras la app está en ejecución; la pantalla aún puede apagarse",
10401043
"settings.general.row.zoom.title": "Zoom level",
10411044
"settings.general.row.zoom.description": "Set the interface zoom level",
10421045
"settings.updates.action.downloading": "Descargando...",

0 commit comments

Comments
 (0)