Fix for USB keyboard

This commit is contained in:
Ken Van Hoeylandt 2026-08-21 21:18:20 +02:00
parent 4fea48f433
commit 700c332219
3 changed files with 32 additions and 6 deletions

View File

@ -36,6 +36,14 @@ error_t lvgl_keyboard_add(struct Device* device, lv_display_t* display, lv_indev
*/
void lvgl_keyboard_remove(lv_indev_t* indev);
/**
* @brief Finds the indev previously created with lvgl_keyboard_add() for the given device, if any.
* @warning Caller must hold the LVGL lock.
* @param[in] device a device of type KEYBOARD_TYPE
* @return the bound indev, or NULL if none is bound to this device
*/
lv_indev_t* lvgl_keyboard_find_by_device(struct Device* device);
/**
* @brief Assigns the indev to the shared keyboard input group, so it can drive focus
* navigation and input for focused widgets.

View File

@ -100,6 +100,20 @@ void lvgl_keyboard_remove(lv_indev_t* indev) {
delete wrapper;
}
lv_indev_t* lvgl_keyboard_find_by_device(Device* device) {
lv_indev_t* indev = lv_indev_get_next(nullptr);
while (indev != nullptr) {
if (lv_indev_get_type(indev) == LV_INDEV_TYPE_KEYPAD) {
auto* wrapper = static_cast<LvglDeviceContext*>(lv_indev_get_driver_data(indev));
if (wrapper != nullptr && wrapper->device == device) {
return indev;
}
}
indev = lv_indev_get_next(indev);
}
return nullptr;
}
void lvgl_keyboard_enable(lv_indev_t* indev) {
check(keyboard_group != nullptr);
lv_indev_set_group(indev, keyboard_group);

View File

@ -63,21 +63,25 @@ void onKeyboardDeviceStarted(Device* device) {
void onKeyboardDeviceStopped(Device* device) {
auto lock = bindingsMutex().asScopedLock();
lock.lock();
lv_indev_t* indev = nullptr;
auto& list = bindings();
for (auto it = list.begin(); it != list.end(); ++it) {
if (it->device == device) {
indev = it->indev;
list.erase(it);
break;
}
}
if (indev == nullptr) {
return;
}
// Not every indev bound to a keyboard device goes through onKeyboardDeviceStarted() and
// bindings() above. lvgl_devices_attach() also binds whatever KEYBOARD_TYPE devices are
// already started at LVGL startup, before this listener is even registered (see
// startKeyboardDeviceListener()'s call site). Look the indev up directly so that path's
// devices still get detached before the kernel device is destructed, instead of leaving a
// dangling indev that reads a freed device on the next LVGL tick.
lvgl_lock();
lvgl_keyboard_remove(indev);
lv_indev_t* indev = lvgl_keyboard_find_by_device(device);
if (indev != nullptr) {
lvgl_keyboard_remove(indev);
}
lvgl_unlock();
}