From ef02737c895d79321ac3cf25d2750df66f8a52a0 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Mon, 2 Mar 2026 13:28:14 +0100 Subject: [PATCH] feat: Prefer ".sleep" over "sleep" for custom image directory (#948) ## Summary * Custom sleep screen images now load from /.sleep directory (preferred), falling back to /sleep for backwards compatibility. The dot-prefix keeps the directory hidden from the file browser. * Rewrote User Guide section 3.6 to document all six sleep screen modes, cover settings, and the updated custom image setup. ## Additional Context * The sleep directoy entry while browsing files was distracting. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _NO_ --- USER_GUIDE.md | 27 +++++++++++++++++---- src/activities/boot_sleep/SleepActivity.cpp | 19 ++++++++++++--- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 0f438fbf..8552cb22 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -308,13 +308,30 @@ If you use the HTTPS listener, use `https://:7200` (`curl -k` only fo ### 3.7 Sleep Screen -You can customize the sleep screen by placing custom images in specific locations on the SD card: +The **Sleep Screen** setting controls what is displayed when the device goes to sleep: -- **Single Image:** Place a file named `sleep.bmp` in the root directory. -- **Multiple Images:** Create a `sleep` directory in the root of the SD card and place any number of `.bmp` images inside. If images are found in this directory, they will take priority over the `sleep.bmp` file, and one will be randomly selected each time the device sleeps. +| Mode | Behavior | +|------|----------| +| **Dark** (default) | The CrossPoint logo on a dark background. | +| **Light** | The CrossPoint logo on a white background. | +| **Custom** | A custom image from the SD card (see below). Falls back to **Dark** if no custom image is found. | +| **Cover** | The cover of the currently open book. Falls back to **Dark** if no book is open. | +| **Cover + Custom** | The cover of the currently open book. Falls back to **Custom** behavior if no book is open. | +| **None** | A blank screen. | -> [!NOTE] -> You'll need to set the **Sleep Screen** setting to **Custom** in order to use these images. +#### Cover settings + +When using **Cover** or **Cover + Custom**, two additional settings apply: + +- **Sleep Screen Cover Mode**: **Fit** (scale to fit, white borders) or **Crop** (scale and crop to fill the screen). +- **Sleep Screen Cover Filter**: **None** (grayscale), **Contrast** (black & white), or **Inverted** (inverted black & white). + +#### Custom images + +To use custom sleep images, set the sleep screen mode to **Custom** or **Cover + Custom**, then place images on the SD card: + +- **Multiple Images (recommended):** Create a `.sleep` directory in the root of the SD card and place any number of `.bmp` images inside. One will be randomly selected each time the device sleeps. (A directory named `sleep` is also accepted as a fallback.) +- **Single Image:** Place a file named `sleep.bmp` in the root directory. This is used as a fallback if no valid images are found in the `.sleep`/`sleep` directory. > [!TIP] > For best results: diff --git a/src/activities/boot_sleep/SleepActivity.cpp b/src/activities/boot_sleep/SleepActivity.cpp index cd6de5fc..35a0ee50 100644 --- a/src/activities/boot_sleep/SleepActivity.cpp +++ b/src/activities/boot_sleep/SleepActivity.cpp @@ -32,9 +32,20 @@ void SleepActivity::onEnter() { } void SleepActivity::renderCustomSleepScreen() const { - // Check if we have a /sleep directory - auto dir = Storage.open("/sleep"); + // Check if we have a /.sleep (preferred) or /sleep directory + const char* sleepDir = nullptr; + auto dir = Storage.open("/.sleep"); if (dir && dir.isDirectory()) { + sleepDir = "/.sleep"; + } else { + if (dir) dir.close(); + dir = Storage.open("/sleep"); + if (dir && dir.isDirectory()) { + sleepDir = "/sleep"; + } + } + + if (sleepDir) { std::vector files; char name[500]; // collect all valid BMP files @@ -74,10 +85,10 @@ void SleepActivity::renderCustomSleepScreen() const { } APP_STATE.lastSleepImage = randomFileIndex; APP_STATE.saveToFile(); - const auto filename = "/sleep/" + files[randomFileIndex]; + const auto filename = std::string(sleepDir) + "/" + files[randomFileIndex]; FsFile file; if (Storage.openFileForRead("SLP", filename, file)) { - LOG_DBG("SLP", "Randomly loading: /sleep/%s", files[randomFileIndex].c_str()); + LOG_DBG("SLP", "Randomly loading: %s/%s", sleepDir, files[randomFileIndex].c_str()); delay(100); Bitmap bitmap(file, true); if (bitmap.parseHeaders() == BmpReaderError::Ok) {