name: adom-screensaver-wake description: How any Adom app (Hydrogen Desktop, adom-desktop, or any tool that needs the laptop screen visible) asks the running Adom screensaver to get out of the way AND keeps the display powered on. Use when an app needs to screenshot, drive UI automation, show an OAuth window, or otherwise SEE the user's screen while the Adom screensaver/billboard might be up. Trigger words, wake the screensaver, dismiss screensaver, adom-screensaver-wake, screensaver wake event, screensaver control port, turn off screensaver from code, screensaver IPC, screensaver is covering the screen, need the screen, ES_DISPLAY_REQUIRED, force display on, screensaver wake.flag, adom-screensaver port.txt.

adom-screensaver-wake, ask the saver to get off the screen

Parent skill: adom-screensaver

When the Adom screensaver / Wiki billboard is up (the user went idle), it is a topmost fullscreen window and, after the display-off timeout, the panel is physically off. Any Adom app that needs to see the screen (screenshot, pup/UI automation, OAuth approval window) must (1) dismiss the saver and (2) make sure the display is on. This skill is that contract.

The two responsibilities (don't skip #2)

  1. Dismiss the saver, signal it (below). It exits immediately.
  2. Hold the display ON yourself, call SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED) in your (the requester's) process and keep it held while you need the screen. The saver pulses the display on as it exits, but that pulse clears when the saver process dies - only a live holder keeps the panel on. Release with SetThreadExecutionState(ES_CONTINUOUS).

If the panel was physically off, give it ~1.5-2s to power on after you hold ES_DISPLAY_REQUIRED before you screenshot.

Three ways to dismiss (all handled by the saver, pick what fits your language)

1. Named event adom-screensaver-wake, guaranteed, instant

Works even after the panel powered off (the saver listens on a blocking thread, not its paint loop). This is the primary path.

PowerShell / adom-desktop relay:

[System.Threading.EventWaitHandle]::OpenExisting('adom-screensaver-wake').Set()
# throws if no saver is running -> nothing to dismiss

Rust (Hydrogen Desktop), via the windows crate:

use windows::Win32::System::Threading::{OpenEventW, SetEvent};
use windows::Win32::System::Threading::EVENT_MODIFY_STATE;
let h = OpenEventW(EVENT_MODIFY_STATE, false, w!("adom-screensaver-wake"))?; // Err = not running
SetEvent(h)?;

2. Flag file, no event API needed (picked up within ~0.75s)

create:  %LOCALAPPDATA%\adom-screensaver\wake.flag    (the saver deletes it on read)
New-Item -ItemType File "$env:LOCALAPPDATA\adom-screensaver\wake.flag" -Force | Out-Null

3. Localhost control port, when you also want STATUS

The saver runs a loopback HTTP server. The port is dynamic (Hyper-V/WSL phantom-reserve fixed ports), so read it from %LOCALAPPDATA%\adom-screensaver\port.txt, never hardcode.

$port = (Get-Content "$env:LOCALAPPDATA\adom-screensaver\port.txt" -Raw).Trim()
# is the saver up, and what is it showing / how long until display-off?
Invoke-WebRequest -UseBasicParsing "http://127.0.0.1:$port/status"
#   -> {"running":true,"slides":16,"currentSlug":"shotlog","currentTitle":"Shotlog",
#       "secondsUntilDisplayOff":47,"power":"ac","battery":98,"waking":false}
# dismiss:
Invoke-WebRequest -UseBasicParsing "http://127.0.0.1:$port/wake" -Method POST

port.txt absent / connection refused == the saver isn't running (nothing to dismiss).

# 1) hold the display on in THIS process for the whole capture
Add-Type 'using System;using System.Runtime.InteropServices;public class P{[DllImport("kernel32.dll")]public static extern uint SetThreadExecutionState(uint f);}'
[P]::SetThreadExecutionState(0x80000000 -bor 0x00000002) | Out-Null   # ES_CONTINUOUS|ES_DISPLAY_REQUIRED
# 2) dismiss the saver
try { [System.Threading.EventWaitHandle]::OpenExisting('adom-screensaver-wake').Set() } catch {}
# 3) let the panel power on if it was off
Start-Sleep -Milliseconds 1800
# 4) ... capture / automate ...
# 5) release when done
[P]::SetThreadExecutionState(0x80000000) | Out-Null                   # ES_CONTINUOUS

Notes

  • Keep-awake is separate. Dismissing the saver never affects adom-stayawake.exe; the machine stays awake regardless.
  • The saver is single-instance (adom-screensaver-singleton mutex) and re-arms on the next idle, so after you're done it simply comes back when the user goes idle again, you don't restart it.
  • For a headless test of the channel without the fullscreen window, run adom-screensaver.scr /serve (control port + wake listener only).