Skip to content

Latest commit

 

History

History
387 lines (285 loc) · 13.9 KB

File metadata and controls

387 lines (285 loc) · 13.9 KB

Trayffeine

Trayffeine is a small Windows tray application that keeps the computer awake while a session is active. It is inspired by tools such as Caffeine, but focuses on a native tray workflow, configurable keep-awake methods, persistent preferences, and a simple installer pipeline.

Development can happen in Windows or WSL, but official Windows installers are produced in GitHub Actions on windows-latest.

Version 1.2.0

Trayffeine 1.2.0 is the current stable release. At this point the app provides:

  • a tray-only Windows experience with no main window
  • active and inactive tray icons, including a pressed visual state while active
  • presets for 15 min, 30 min, 1 h, 2 h, and Infinite
  • automatic shutdown when a timed session expires
  • a single toast notification when a timed session ends
  • double-click on the tray icon to toggle infinite mode
  • persistent language, logging, keep-awake method, presence compatibility, and startup preferences
  • persistent restore of infinite mode across launches
  • optional Start with Windows from the tray preferences menu
  • configurable keep-awake methods: Smart, Windows API, F15, and Shift
  • a presence compatibility mode that uses F15 as a best-effort signal for apps such as Teams
  • configured and effective keep-awake method summaries in the tray menu
  • copyable diagnostics for support
  • runtime localization for pt-BR, en, and es
  • rotating log files and support actions from the tray menu
  • a per-user Windows installer built with PyInstaller and Inno Setup

Installation

Preferred installation on Windows:

winget install RodrigoAntonioli.Trayffeine

To upgrade later:

winget upgrade RodrigoAntonioli.Trayffeine

If you prefer manual installation, download the latest installer from the GitHub Releases page and run it on Windows.

Installer behavior:

  • installs to %LocalAppData%\Programs\Trayffeine
  • always creates a Start Menu shortcut for the current user
  • offers to launch Trayffeine after installation
  • closes a running Trayffeine.exe during install or uninstall when needed

Notes:

  • the installer itself is still unsigned
  • winget is the preferred install path and avoids most browser-download friction
  • direct execution of the downloaded installer may still trigger Windows or SmartScreen warnings
  • code signing is not part of the repository yet, so keep the unsigned-installer caveat in mind
  • the Start Menu shortcut is created in the current-user Start Menu, not in ProgramData
  • searching for Trayffeine from the Windows Start menu should find the app normally

How It Works

Trayffeine keeps the machine awake only while a session is active.

Session modes:

  • Infinite: stays active until you stop it manually
  • timed presets: stop automatically when time runs out

While active:

  • the tray icon switches to the active state
  • the tooltip shows elapsed and remaining time
  • the menu keeps stable summary rows and direct actions

When a timed session ends:

  • the app returns to inactive mode
  • the keep-awake backend is stopped
  • the tray icon returns to the inactive state
  • a notification is shown once

Double-click behavior:

  • if Trayffeine is inactive, double-click enables infinite mode
  • if Trayffeine is already active, double-click turns the session off

Tray Menu

The tray menu is organized into stable sections:

  • status rows
    • Trayffeine v1.2.0
    • a stable summary such as Inactive, Active until 14:32, or Infinite mode active
    • the configured or effective keep-awake method, such as Method: Smart -> Windows API
  • primary actions
    • Infinite mode
    • Activate for >
    • Stop
  • Preferences >
    • Presence compatibility
    • Keep-awake method >
    • Start with Windows
    • Language >
  • Support >
    • Copy diagnostics
    • How it works
    • Detailed logging
    • Open Logs Folder
    • Clear Logs
  • Quit

The Windows tray menu is a native popup, so its contents do not live-refresh while it stays open. Trayffeine therefore keeps the menu focused on stable summaries and uses the tooltip for the live counter.

Keep-Awake Methods

Trayffeine supports four methods:

  • Smart
    • tries Windows API
    • if that fails technically, falls back to F15
    • if F15 fails technically, falls back to Shift
  • Windows API
    • uses SetThreadExecutionState while the session is active
  • F15
    • simulates F15 periodically
  • Shift
    • simulates Shift periodically

Notes:

  • Smart fallback is technical only; it does not try to prove that Windows or Teams stayed active
  • if your main goal is preventing sleep/display idle, Windows API is the strongest option
  • if your main goal is presence-style activity in apps, F15 may work better depending on the environment

Presence Compatibility

Presence compatibility is a persistent preference for environments where an app reacts better to lightweight keyboard activity than to the native Windows execution-state API.

When enabled:

  • Trayffeine preserves your normal keep-awake method selection
  • the effective keep-awake method becomes F15
  • the tray menu reports this explicitly, for example Presence compatibility: F15
  • turning the preference off restores the normal saved method immediately

This is intentionally best effort. It can help apps that observe activity-like input, but it does not integrate with Teams and does not guarantee a Teams Available status. Teams and similar apps may also consider calendar state, app focus, lock state, device activity, meeting/call status, mobile clients, and organization-controlled behavior.

Recommended guidance:

  • use Windows API when the goal is preventing sleep or display idle
  • try Presence compatibility when an app appears to ignore sleep-prevention signals but reacts to activity-like input
  • leave the normal method on Smart if you want Trayffeine to use the strongest sleep-prevention path when presence compatibility is off

Diagnostics

Support > Copy diagnostics copies a short support bundle to the clipboard. It is stable English text so it can be pasted into GitHub issues, support messages, or release test notes regardless of the selected UI language.

Diagnostics include:

  • Trayffeine version
  • language selection and effective locale
  • current session summary
  • configured and effective keep-awake methods
  • presence compatibility, detailed logging, and Start with Windows states
  • settings and log file paths, with the current profile prefix replaced by %LOCALAPPDATA% or %USERPROFILE%

Preferences and Persistence

Trayffeine persists settings in %LOCALAPPDATA%\Trayffeine\settings.json.

Persisted preferences:

  • language selection
  • detailed logging preference
  • keep-awake method
  • presence compatibility mode
  • whether Trayffeine should start with Windows
  • whether infinite mode should be restored on next launch

Startup behavior:

  • Start with Windows is optional and disabled by default
  • the EXE/Inno Setup/WinGet install registers itself in the current-user Windows Run key
  • the future MSIX package uses its declared Windows startup task instead, while keeping the same tray preference
  • timed sessions never resume after a restart
  • infinite mode can resume if it was active when the app last saved state

First launch defaults, when no settings file exists:

  • infinite mode restored immediately
  • detailed logging enabled
  • keep-awake method set to Smart
  • presence compatibility disabled
  • Start with Windows disabled
  • language set to Auto

Localization

Supported runtime locales:

  • en
  • pt-BR
  • es

Localization behavior:

  • English is the source and fallback language in code
  • the app detects the system locale at startup
  • Auto follows the system locale
  • explicit language selection persists across launches

Logging and Support

Runtime logs live in %LOCALAPPDATA%\Trayffeine\logs\trayffeine.log.

Logging behavior:

  • default level is WARNING
  • detailed logging maps to INFO
  • log files rotate automatically at 256 KB with 3 backups
  • high-frequency internal tray events are intentionally not logged at INFO

Detailed logging captures useful actions such as:

  • app start and exit
  • preset selection
  • infinite mode toggles
  • language changes
  • keep-awake method changes
  • presence compatibility toggles
  • toggling Start with Windows
  • timer expiration
  • opening the logs folder
  • clearing logs

Support actions:

  • Copy diagnostics copies version, language, session, method, preference, settings path, and log path information to the clipboard
  • How it works opens a short help dialog
  • Detailed logging enables or disables persistent INFO logging
  • Start with Windows enables or disables current-user startup from Preferences
  • Open Logs Folder opens the logs directory
  • Clear Logs asks for confirmation, removes the current log and rotated backups, and recreates a fresh current log file

Crash behavior:

  • unexpected exceptions are logged
  • the app shows a small Windows error dialog pointing to the logs folder

Environment override:

  • TRAYFFEINE_LOG_LEVEL takes precedence over the persisted detailed logging preference for that process

Limitations

  • Trayffeine is Windows-only at runtime
  • the installer is still unsigned
  • SmartScreen reputation is not solved in this repository
  • the app does not bypass Win + L, corporate lock policies, or other enforced security controls
  • Teams or similar presence indicators are not guaranteed, because they do not depend only on Windows idle state
  • presence compatibility is an app-activity compatibility mode, not a Teams integration
  • tray behavior is partially unit-tested, but final confidence for UI behavior still comes from real Windows validation

Project Layout

  • src/trayffeine/app.py: bootstrap, settings load, single-instance guard, crash boundary
  • src/trayffeine/tray.py: tray icon, menu, support actions, notifications
  • src/trayffeine/service.py: background worker, timer expiration, keep-awake cadence
  • src/trayffeine/session.py: session state and preset timing
  • src/trayffeine/presenter.py: tooltip, summaries, and notification text assembly
  • src/trayffeine/diagnostics.py: stable support diagnostics text
  • src/trayffeine/i18n.py: runtime localization
  • src/trayffeine/settings.py: persisted settings model and JSON storage
  • src/trayffeine/app_logging.py: rotating file logging and cleanup helpers
  • src/trayffeine/keepawake.py: stable keep-awake method ids
  • src/trayffeine/win32_tray.py: Windows-specific tray wrapper for double-click handling
  • src/trayffeine/windows.py: Windows keep-awake backends, dialogs, mutex, shell helpers, startup registration
  • packaging/windows/: PyInstaller spec, build script, Inno Setup installer script
  • packaging/msix/: isolated MSIX preflight build and manifest template for a future Store submission
  • tests/: unit and smoke-style tests
  • CONTRIBUTING.md: contributor workflow and validation notes
  • docs/ROADMAP.md: internal release buckets and backlog notes
  • CHANGELOG.md: project history and milestone summary
  • requirements-windows-build.lock and requirements-msix-build.lock: exact, hash-verified dependencies for distributable builds

Local Development

WSL workflow

Use this loop for WSL or Linux-style shells:

python3.13 -m venv .venv
. .venv/bin/activate
python -m pip install -e .[dev]
python scripts/generate_assets.py
ruff check .
pytest

Windows workflow

Run the app from a real Windows path when you need interactive tray validation:

py -3.13 -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -e .[dev,build]
python scripts\generate_assets.py
python -m trayffeine

Packaging and Releases

The release workflow builds:

  1. a PyInstaller onedir bundle
  2. an Inno Setup installer .exe

Manual Windows packaging:

py -3.13 -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --require-hashes -r requirements-windows-build.lock
python scripts\generate_assets.py
powershell -ExecutionPolicy Bypass -File packaging\windows\build.ps1 -Version 1.2.0 -Clean

GitHub Actions:

  • CI runs on pushes to main and on pull requests
  • Preview Build runs on pull requests and manual dispatch, building a Windows installer artifact without creating a release
  • Release runs only on validated tags such as v1.2.0, v1.2.0-beta1, or v1.2.0-beta.1
  • beta tags publish prereleases and skip WinGet
  • stable tags such as v1.2.0 publish normal releases
  • distributable builds use commit-pinned Actions, hash-locked Python dependencies, and verified Inno Setup/WingetCreate binaries
  • publication is separated from the unprivileged build and is gated by the protected release GitHub Environment

Preview test flow:

  • open a pull request for the branch
  • wait for the Preview Build workflow to finish
  • download the uploaded installer artifact from the workflow run
  • test that installer on Windows before tagging a release

Future Microsoft Store MSIX package

MSIX preparation is separate from the existing public installer and WinGet channel. The MSIX Preview Build workflow creates an unsigned, non-Store preflight artifact for pull requests and never creates a GitHub Release. See docs/msix.md for local build steps, package behavior, Partner Center identity values, and the later signing/submission checklist.

Validation

Expected local validation:

. .venv/bin/activate
ruff check .
pytest

Support

When reporting a bug, include:

  • the exact Trayffeine version
  • your Windows version
  • steps to reproduce
  • the text from Support > Copy diagnostics
  • the contents of %LOCALAPPDATA%\Trayffeine\logs\trayffeine.log

Diagnostics replace the standard profile prefix with an environment-variable marker. Review copied diagnostics and logs before posting them publicly because logs can still contain environment-specific details.

Contribution notes live in CONTRIBUTING.md.

License

Trayffeine is available under the MIT License.