Skip to content

ES_USER_PRESENT causes SetThreadExecutionState to silently fail -- system sleeps despite caffeinate #3

@VertigoRay

Description

@VertigoRay

Description

When -u (UserActive / ES_USER_PRESENT) is included in any flag combination, SetThreadExecutionState returns 0 (failure) and no assertions are set at all. The system sleeps as if caffeinate was never started.

This affects both bundled (caffeinate -disu) and individual (caffeinate -d -i -s -u) flag usage.

Expected behavior

caffeinate -d -i -s -u should prevent the system and display from sleeping.

Actual behavior

SetThreadExecutionState returns 0 (NULL = failure). No sleep prevention is active. System goes to sleep normally.

Root cause

ES_USER_PRESENT (0x00000004) is deprecated on modern Windows. From the Win32 docs:

ES_USER_PRESENT - This value is not supported.

When combined with other flags, the entire call fails and none of the requested states are set.

The return value was discarded ($null = ...), so the failure was completely silent.

Verified behavior

Flags Return
ES_CONTINUOUS OK
ES_CONTINUOUS | ES_SYSTEM_REQUIRED OK
ES_CONTINUOUS | ES_DISPLAY_REQUIRED OK
ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED OK
ES_CONTINUOUS | ES_USER_PRESENT 0 (FAIL)
ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED | ES_USER_PRESENT 0 (FAIL)
ES_USER_PRESENT alone 0 (FAIL)

Fix

  • Never pass ES_USER_PRESENT to the API
  • When -u is requested, substitute ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED
  • Check the return value of SetThreadExecutionState and warn on failure
  • Re-assert execution state every 30s as a safety net

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions