diff --git a/src/lib/electron/electron_relay.ts b/src/lib/electron/electron_relay.ts index bb47f939..b957c8f3 100644 --- a/src/lib/electron/electron_relay.ts +++ b/src/lib/electron/electron_relay.ts @@ -413,6 +413,38 @@ export async function set_wallpaper({ return await native.set_wallpaper({ path, url, url_external, display, api_key, account_id }); } +/** + * Restores the macOS default wallpaper on all displays. + * Scans /System/Library/Desktop Pictures/ for the first .heic file — works across + * all recent macOS versions without needing to know the version name. + * No-op on non-macOS (Linux/Windows return success:false from run_osascript). + */ +export async function restore_macos_default_wallpaper( + display: 'all' | 'primary' | 'external' = 'all' +): Promise<{ success: boolean; error?: string }> { + const display_target = + display === 'primary' + ? 'tell desktop 1' + : display === 'external' + ? 'tell desktop 2' + : 'tell every desktop'; + + const script = ` +set pic_path to do shell script "ls '/System/Library/Desktop Pictures/'*.heic 2>/dev/null | head -1" +if pic_path is "" then + error "No default macOS wallpaper (.heic) found in /System/Library/Desktop Pictures/" +end if +tell application "System Events" + ${display_target} + set picture to pic_path + end tell +end tell +`.trim(); + + const result = await run_osascript(script); + return result ?? { success: false, error: 'Native bridge not available' }; +} + export async function update_app(args: { source: 'url' | 'file'; url?: string; diff --git a/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_wallpaper.svelte b/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_wallpaper.svelte index 9236d68b..700aac56 100644 --- a/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_wallpaper.svelte +++ b/src/routes/events/[event_id]/(launcher)/cfg_components/launcher_cfg_wallpaper.svelte @@ -4,7 +4,7 @@ import { events_func } from '$lib/ae_events/ae_events_functions'; import { events_loc } from '$lib/stores/ae_events_stores'; import * as native from '$lib/electron/electron_relay'; import Launcher_Cfg_Section from './launcher_cfg_section.svelte'; -import { FlaskConical, Image, Monitor, Save, Zap } from '@lucide/svelte'; +import { FlaskConical, Image, Monitor, RotateCcw, Save, Zap } from '@lucide/svelte'; interface Props { on_expand?: () => void; @@ -23,6 +23,7 @@ let url_input = $state(''); let url_external_input = $state(''); let save_status = $state(''); let apply_status = $state(''); +let restore_status = $state(''); let last_device_id: string | null = null; function get_native_device(): NativeDeviceLike | null { @@ -148,6 +149,20 @@ async function handle_apply() { } } +async function handle_restore_default() { + restore_status = 'Restoring...'; + const result = await native.restore_macos_default_wallpaper('all'); + if (result?.success) { + // Clear tracked applied URL so the next config URL re-applies correctly. + $events_loc.launcher.wallpaper_applied_url = null; + $events_loc.launcher.wallpaper_applied_url_external = null; + restore_status = 'Restored ✓'; + } else { + restore_status = `Error: ${(result as any)?.error ?? 'Unknown error'}`; + } + setTimeout(() => { if (restore_status.startsWith('Restored') || restore_status.startsWith('Error')) restore_status = ''; }, 4000); +} + async function handle_save_and_apply() { await handle_save(); if (save_status !== 'Save failed' && save_status !== 'No device loaded') { @@ -276,6 +291,16 @@ const section_description = $derived( Save & Apply + + {#if $ae_loc.is_native || $ae_loc.edit_mode} + + {/if} + {#if save_status}