Skip to content

Commit 45541b5

Browse files
synleclaude
andcommitted
feat: add Keep Awake toggle to prevent system sleep (v2.1.0)
Add a "Keep Awake" button below the profile buttons that prevents the system from idle-sleeping and the display from turning off, similar to the Caffeine app. Uses the cross-platform `keepawake` crate (v0.6) which supports macOS (IOKit), Windows (SetThreadExecutionState), and Linux (D-Bus). The guard is stored as Mutex<Option<KeepAwake>> in AppState — creating enables, dropping disables. Includes frontend component with tests, Rust unit tests, and version bump to 2.1.0. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 17b0abe commit 45541b5

13 files changed

Lines changed: 946 additions & 143 deletions

File tree

CLAUDE.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Project Overview
44

5-
Cross-platform desktop system tray application for controlling monitor brightness, contrast, dark mode, and volume. Built with **Tauri v2** (Rust backend) + **React 18** (TypeScript frontend) + **Vite 6**.
5+
Cross-platform desktop system tray application for controlling monitor brightness, contrast, dark mode, volume, and keep-awake (sleep prevention). Built with **Tauri v2** (Rust backend) + **React 18** (TypeScript frontend) + **Vite 6**.
66

77
Display and dark mode operations are delegated to the [display-dj CLI](https://github.com/synle/display-dj-cli), which runs as a bundled HTTP server sidecar. The Tauri backend makes HTTP requests to it. Volume control remains platform-specific in Rust.
88

@@ -30,15 +30,16 @@ cd src-tauri && cargo test # Run all Rust backend tests
3030
### Frontend Tests (Vitest + React Testing Library)
3131

3232
- **Setup**: `src/test/setup.ts` — Configures jsdom, jest-dom matchers, and Tauri API mocks
33-
- **Unit tests**: `src/components/*.test.tsx` — Tests for each component (Header, Slider, DarkModeToggle, VolumeControl, AllMonitorsControl, MonitorControl)
33+
- **Unit tests**: `src/components/*.test.tsx` — Tests for each component (Header, Slider, DarkModeToggle, VolumeControl, AllMonitorsControl, MonitorControl, KeepAwakeToggle)
3434
- **Smoke test**: `src/App.test.tsx` — Verifies App renders without errors, fetches initial data, handles backend failures gracefully
3535
- Tauri `invoke()` and `listen()` are mocked globally in the test setup
3636

3737
### Backend Tests (Rust)
3838

39-
- **Unit tests**: Inline `#[cfg(test)]` modules in `config.rs` and `display.rs`
39+
- **Unit tests**: Inline `#[cfg(test)]` modules in `config.rs`, `display.rs`, and `keep_awake.rs`
4040
- `config.rs`: Serialization/deserialization, defaults, camelCase conventions, file roundtrips, CommandValue enum variants, MonitorMetadata serde, effective min brightness, backward-compatible deserialization of old configs, preferences with monitorConfigs roundtrip
4141
- `display.rs`: `DjDisplay` to `Monitor` conversion (including uid computation), `merge_with_configs` (rename, sort), `reconcile_migrated_configs`, `ensure_metadata_for_monitors`, Monitor serde
42+
- `keep_awake.rs`: KeepAwake guard creation, Mutex<Option<KeepAwake>> pattern (enable/disable/re-enable)
4243
- **Smoke test**: `src-tauri/tests/smoke.rs` — Integration test verifying the crate compiles, links, and public API (AppState, run) is accessible
4344

4445
### CI
@@ -76,14 +77,15 @@ These are documented inline in `config.rs` with WARNING comments.
7677
- Preferences use `#[serde(default)]` so old config files missing new fields gracefully fall back to defaults
7778
- Brightness values are clamped to `effective_min_brightness()` which enforces an absolute floor of 5
7879
- Contrast is DDC-only (`Option<u32>` / `number | null`): built-in displays return `null`. The contrast slider is hidden by default and toggled via the `showContrast` preference in Settings
80+
- Keep Awake uses the `keepawake` crate (v0.6) to prevent system idle sleep and display sleep. The guard is stored as `Mutex<Option<KeepAwake>>` in `AppState` — creating the guard enables keep-awake, dropping it (setting to `None`) releases the assertion. Works on macOS (IOKit), Windows (SetThreadExecutionState), and Linux (D-Bus). The `set_keep_awake` command is `async` to avoid the tray icon pitfall.
7981

8082
## Related Projects
8183

8284
- **[display-dj-cli](https://github.com/synle/display-dj-cli)** — The Rust CLI/HTTP server that handles all display operations (brightness, contrast, dark mode). Bundled as a Tauri sidecar. Source at `/Users/syle/Downloads/display-dj-cli`. When bumping the sidecar version, always review upstream changes in that repo.
8385

8486
## Dependencies
8587

86-
The display-dj CLI sidecar handles all platform-specific display dependencies internally. No external tools need to be installed for display control.
88+
The display-dj CLI sidecar handles all platform-specific display dependencies internally. No external tools need to be installed for display control. The `keepawake` crate handles sleep prevention natively on all platforms (macOS IOKit, Windows SetThreadExecutionState, Linux D-Bus).
8789

8890
### Sidecar binaries
8991

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "display-dj",
3-
"version": "2.0.0",
3+
"version": "2.1.0",
44
"description": "Cross-platform desktop app for monitor brightness, contrast, and dark mode control",
55
"displayDjCliVersion": "v0.5.0",
66
"scripts": {

0 commit comments

Comments
 (0)