Files
tactility/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp
T
Shadowtrance a4dc633063 Feature additions (#434)
Lots of things "ported" over from the "enhanced" fork. With some adjustments here and there.

KeyboardBacklight driver (for T-Deck only currently)
Trackball driver (for T-Deck only currently)
Keyboard backlight sleep/wake (for T-Deck only currently...also requires keyboard firmware update)
Display sleep/wake
Files - create file/folder
Keyboard settings (for T-Deck only currently)
Time & Date settings tweaks
Locale settings tweaks
Systeminfo additions
Espnow wifi coexist

initI2cDevices - moved to T-deck init.cpp / initBoot
KeyboardInitService - removed,  moved to T-deck init.cpp / initBoot
Adjusted TIMER_UPDATE_INTERVAL to 2 seconds.
Added lock to ActionCreateFolder

Maybe missed some things in the list.

Display wake could do with some kind of block on wake first touch to prevent UI elements being hit when waking device with touch. Same with encoder/trackball/keyboard press i guess.

The original code was written by @cscott0108 at https://github.com/cscott0108/tactility-enhanced-t-deck
2026-01-02 12:14:55 +01:00

98 lines
3.6 KiB
C++

#ifdef ESP_PLATFORM
#include <Tactility/service/ServiceRegistration.h>
#include <Tactility/service/ServiceManifest.h>
#include <Tactility/service/ServiceContext.h>
#include <Tactility/Timer.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/settings/KeyboardSettings.h>
#include <Tactility/hal/keyboard/KeyboardDevice.h>
namespace keyboardbacklight {
bool setBrightness(uint8_t brightness);
}
namespace tt::service::keyboardidle {
constexpr auto* TAG = "KeyboardIdle";
class KeyboardIdleService final : public Service {
std::unique_ptr<Timer> timer;
bool keyboardDimmed = false;
settings::keyboard::KeyboardSettings cachedKeyboardSettings;
static std::shared_ptr<hal::keyboard::KeyboardDevice> getKeyboard() {
return hal::findFirstDevice<hal::keyboard::KeyboardDevice>(hal::Device::Type::Keyboard);
}
void tick() {
// Settings are now cached and event-driven (no file I/O in timer callback!)
// This prevents watchdog timeout from blocking the Timer Service task
// Query LVGL inactivity once for both checks
uint32_t inactive_ms = 0;
if (lvgl::lock(100)) {
inactive_ms = lv_disp_get_inactive_time(nullptr);
lvgl::unlock();
}
// Handle keyboard backlight
auto keyboard = getKeyboard();
if (keyboard != nullptr && keyboard->isAttached()) {
// If timeout disabled, ensure backlight restored if we had dimmed it
if (!cachedKeyboardSettings.backlightTimeoutEnabled || cachedKeyboardSettings.backlightTimeoutMs == 0) {
if (keyboardDimmed) {
keyboardbacklight::setBrightness(cachedKeyboardSettings.backlightEnabled ? cachedKeyboardSettings.backlightBrightness : 0);
keyboardDimmed = false;
}
} else {
if (!keyboardDimmed && inactive_ms >= cachedKeyboardSettings.backlightTimeoutMs) {
keyboardbacklight::setBrightness(0);
keyboardDimmed = true;
} else if (keyboardDimmed && inactive_ms < 100) {
keyboardbacklight::setBrightness(cachedKeyboardSettings.backlightEnabled ? cachedKeyboardSettings.backlightBrightness : 0);
keyboardDimmed = false;
}
}
}
}
public:
bool onStart(TT_UNUSED ServiceContext& service) override {
// Load settings once at startup and cache them
// This eliminates file I/O from timer callback (prevents watchdog timeout)
cachedKeyboardSettings = settings::keyboard::loadOrGetDefault();
// Note: Settings changes require service restart to take effect
// TODO: Add KeyboardSettingsChanged events for dynamic updates
timer = std::make_unique<Timer>(Timer::Type::Periodic, [this]{ this->tick(); });
timer->setThreadPriority(Thread::Priority::Lower);
timer->start(250); // check 4x per second for snappy restore
return true;
}
void onStop(TT_UNUSED ServiceContext& service) override {
if (timer) {
timer->stop();
timer = nullptr;
}
// Ensure keyboard restored on stop
auto keyboard = getKeyboard();
if (keyboard && keyboardDimmed) {
keyboardbacklight::setBrightness(cachedKeyboardSettings.backlightEnabled ? cachedKeyboardSettings.backlightBrightness : 0);
keyboardDimmed = false;
}
}
};
extern const ServiceManifest manifest = {
.id = "KeyboardIdle",
.createService = create<KeyboardIdleService>
};
}
#endif