Objects not receiving KEY events

Description

I can’t seem to get any KEY events on any objects I create. After searching this forum and spending a day trying to get this to work I’m posting this here hoping I’ve missed something silly and someone can point out my mistake.

What MCU/Processor/Board and compiler are you using?

Using Zephyr rtos with the following hardware targets

  • nRF5340 on ublox Nora B1 devkit
  • native_posix target

What LVGL version are you using?

8.2

What do you want to achieve?

I would like to use the buttons as encoder input to navigate menus and interact with widgets. I’ve followed the examples but my widgets do not seem to receive the KEY events.

What have you tried so far?

I have tried using different objects like menu, roller, and a simple button (exampled below). Also tried using the keypad input without success. When debugging I see that the encoder_buttons is setting the indev_data values when physical buttons are pressed. Unfortunately my objects never seem to get those events. When I set the object’s event callback to LV_EVENT_ALL, I see a bunch of drawing events happening in the beginning but no KEY_ events seem to come through. I have made sure to add my objects to a group.

Any help would be greatly appreciated!

Code to reproduce

main_menu_init is called from the main thread at startup

// Objects must be added to the input group to receive input events
lv_group_t *input_group;
// Call back for input events
static bool encoder_buttons(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
  struct ButtonStateMessage *last_button = user_input_get_last_button();
  if (last_button->name == UP_BUTTON)
  {
    data->key = LV_KEY_LEFT;
  }
  else if (last_button->name == DOWN_BUTTON)
  {
    data->key = LV_KEY_RIGHT;
  }
  else if (last_button->name == SELECT_BUTTON)
  {
    data->key = LV_KEY_ENTER;
  }
  if (last_button->state == BUTTON_PRESSED)
  {
    LOG_DBG("Pressed");
    data->state = LV_INDEV_STATE_PRESSED;
  }
  else
  {
    data->state = LV_INDEV_STATE_RELEASED;
  }
  return false;
}

void register_input()
{
  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_ENCODER;
  indev_drv.read_cb = encoder_buttons;

  lv_indev_t *my_indev = lv_indev_drv_register(&indev_drv);

  if (my_indev == NULL)
  {
    LOG_ERR("Unable to register input");
  }

  lv_indev_set_group(my_indev, input_group);
  lv_group_set_default(input_group);
}

void main_menu_init()
{
  register_input();

  lv_obj_t *btn = lv_btn_create(lv_scr_act());
  lv_obj_set_size(btn, 100, 30);
  lv_obj_center(btn);
  lv_obj_add_event_cb(btn, event_cb, LV_EVENT_ALL, NULL);
  lv_group_add_obj(lv_group_get_default(), btn);

  lv_obj_t *label = lv_label_create(btn);
  lv_label_set_text(label, "A Button");
  lv_obj_center(label);
}

Calls to lv_task_handler are performed in a thread with a 2 sec startup delay.

void ui_thread_handler()
{

  while (1)
  {
    lv_task_handler();
    k_msleep(10);
  }
}
K_THREAD_DEFINE(ui_thread, 4096, ui_thread_handler, NULL, NULL, NULL, 1, 0, 2000);

I believe I solved the issue. Putting the solution here for anyone else who may make the same mistake in the future. The problem was my group was setup incorrectly :person_facepalming:. I had initialized my group with the line

lv_group_t *input_group;

I neglected to setup the group by calling:

lv_group_create();

So when creating a group, be sure to do so correctly with:

lv_group_t *your_group = lv_group_create();

It is clearly stated in the docs to do so. I just failed to catch my omission.

Cheers!