diff --git a/Tactility/Private/Tactility/service/displayidle/DisplayIdleService.h b/Tactility/Private/Tactility/service/displayidle/DisplayIdleService.h index 53b31697..38afa07e 100644 --- a/Tactility/Private/Tactility/service/displayidle/DisplayIdleService.h +++ b/Tactility/Private/Tactility/service/displayidle/DisplayIdleService.h @@ -37,6 +37,7 @@ class DisplayIdleService final : public Service { bool backlightOff = false; static void stopScreensaverCb(lv_event_t* e); + void stopScreensaverLocked(); /** @pre Caller must hold LVGL lock */ void activateScreensaver(); diff --git a/Tactility/Source/app/launcher/Launcher.cpp b/Tactility/Source/app/launcher/Launcher.cpp index a7f308ea..ecb97cd4 100644 --- a/Tactility/Source/app/launcher/Launcher.cpp +++ b/Tactility/Source/app/launcher/Launcher.cpp @@ -54,6 +54,11 @@ class LauncherApp final : public App { lv_obj_set_style_outline_pad(apps_button, 2, LV_STATE_FOCUSED); lv_obj_set_style_outline_color(apps_button, lv_theme_get_color_primary(apps_button), LV_STATE_FOCUSED); + auto* default_group = lv_group_get_default(); + if (default_group) { + lv_group_add_obj(default_group, apps_button); + } + // create the image first auto* button_image = lv_image_create(apps_button); lv_obj_set_style_text_font(button_image, lvgl_get_launcher_icon_font(), LV_STATE_DEFAULT); @@ -218,6 +223,16 @@ public: lv_obj_set_style_shadow_width(power_button, 0, LV_STATE_DEFAULT); lv_obj_set_style_bg_opa(power_button, 0, LV_PART_MAIN); + // Add high-contrast focus outline for monochrome / RLCD screens + lv_obj_set_style_outline_width(power_button, 2, LV_STATE_FOCUSED); + lv_obj_set_style_outline_pad(power_button, 2, LV_STATE_FOCUSED); + lv_obj_set_style_outline_color(power_button, lv_theme_get_color_primary(power_button), LV_STATE_FOCUSED); + + auto* default_group = lv_group_get_default(); + if (default_group) { + lv_group_add_obj(default_group, power_button); + } + auto* power_label = lv_label_create(power_button); lv_label_set_text(power_label, LV_SYMBOL_POWER); lv_obj_set_style_text_color(power_label, lv_theme_get_color_primary(parent), LV_STATE_DEFAULT); diff --git a/Tactility/Source/service/displayidle/DisplayIdle.cpp b/Tactility/Source/service/displayidle/DisplayIdle.cpp index 8bf5771c..a7164033 100644 --- a/Tactility/Source/service/displayidle/DisplayIdle.cpp +++ b/Tactility/Source/service/displayidle/DisplayIdle.cpp @@ -32,17 +32,10 @@ static std::shared_ptr getDisplay() { void DisplayIdleService::stopScreensaverCb(lv_event_t* e) { auto* self = static_cast(lv_event_get_user_data(e)); - lv_event_stop_bubbling(e); - self->stopScreensaverRequested.store(true, std::memory_order_release); - lv_display_trigger_activity(nullptr); + self->stopScreensaverLocked(); } -void DisplayIdleService::stopScreensaver() { - if (!lvgl::lock(100)) { - // Lock failed - keep flag set to retry on next tick - return; - } - +void DisplayIdleService::stopScreensaverLocked() { const auto restoreDuty = cachedDisplaySettings.backlightDuty; const bool wasDimmed = displayDimmed; @@ -54,7 +47,6 @@ void DisplayIdleService::stopScreensaver() { lv_obj_delete(screensaverOverlay); screensaverOverlay = nullptr; } - lvgl::unlock(); stopScreensaverRequested.store(false, std::memory_order_relaxed); // Reset auto-off state @@ -69,6 +61,15 @@ void DisplayIdleService::stopScreensaver() { displayDimmed = wasDimmed ? false : displayDimmed; } +void DisplayIdleService::stopScreensaver() { + if (!lvgl::lock(100)) { + // Lock failed - keep flag set to retry on next tick + return; + } + stopScreensaverLocked(); + lvgl::unlock(); +} + void DisplayIdleService::activateScreensaver() { lv_obj_t* top = lv_layer_top(); @@ -203,6 +204,12 @@ void DisplayIdleService::tick() { } bool DisplayIdleService::onStart(ServiceContext& service) { + auto display = getDisplay(); + if (display != nullptr && !display->supportsBacklightDuty()) { + LOGGER.info("Monochrome/RLCD display detected (no backlight control): disabling screensaver tick timer"); + return true; + } + // Seed random number generator for varied screensaver patterns srand(static_cast(time(nullptr)));