Receiving keyboard events in main window?

Description

I have a windowed application where i want to receive keyboard events “globally” in the application

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

PC Linux using the lv_port_linux latest from master. Runing on the SDL backend.

What LVGL version are you using?

Git submodule in port at HEAD detached at origin/release/v9.1

What do you want to achieve?

Receive keyboard events for the top level widget/window but key events seems supressed and not reaching the top window. Could this be some focus problem?

What have you tried so far?

First i tried to attach a callback for the LV_EVENT_KEY event. This works if i have a text entry in the window and set the LV_OBJ_FLAG_EVENT_BUBBLE on it but without that i get no key events.

Then i tried adding a callback on the keyboard indev. This works partially but i get only zeroes for key and state. Further more key events seems to accumulate. First key press reports two events, which would be expected. But next press returns 4 events, next 6 events an so on.

Code to reproduce

Trying to attach to indev callback:

static void indev_cb(lv_indev_t* indev, lv_indev_data_t *data)
{
	printf("Indev cb, type: %d key: %d state: %d\n", lv_indev_get_type(indev), data->key, data->state);
}

static void lv_linux_disp_init(void)
{
	const int width = atoi(getenv("LV_SDL_VIDEO_WIDTH") ? : "800");
	const int height = atoi(getenv("LV_SDL_VIDEO_HEIGHT") ? : "480");

	display = lv_sdl_window_create(width, height);

	lv_group_t *g = lv_group_create();
	lv_group_set_default(g);

	lv_indev_t *mouse = lv_sdl_mouse_create();
	lv_indev_set_group(mouse, lv_group_get_default());

	lv_indev_t *mousewheel = lv_sdl_mousewheel_create();
	lv_indev_set_group(mousewheel, lv_group_get_default());

	lv_indev_t *keyboard = lv_sdl_keyboard_create();
	lv_indev_set_read_cb(keyboard, indev_cb);
	lv_indev_set_group(keyboard, lv_group_get_default());
}

Attach event callback to main window:

static void event_cb(lv_event_t *e)
{
	switch(lv_event_get_code(e))
	{
	case LV_EVENT_KEY:
		printf("Got key: %d\n",lv_indev_get_key(lv_indev_active()));
				break;
	default:
		printf("Unhandled event: %d\n", lv_event_get_code(e));
	break;
	}

}

static lv_event_dsc_t *evdsc;
static void setup(void)
{
	lv_obj_t *parent = lv_screen_active();
#if 1
	// With this enabled i get key events for the main window.
	entry = lv_textarea_create(parent);
	lv_obj_align(entry, LV_ALIGN_CENTER, 0, 50);
	lv_obj_set_width(entry, 150);
	lv_textarea_set_one_line(entry, true);
	lv_textarea_set_max_length(entry, 12);
	lv_obj_add_flag(entry, LV_OBJ_FLAG_EVENT_BUBBLE);
#endif
	evdsc = lv_obj_add_event_cb(parent, event_cb, LV_EVENT_ALL, NULL);
}

Ok, so it seems that i have to add the main window to the “default group” for this to work.

lv_group_add_obj(lv_group_get_default(), lv_screen_active());

Moving to the target platform that uses fbdev and evdev this stopped working. But adding a

lv_group_focus_obj(lv_screen_active());

As mentioned Force focus to another object using code - #4 by exxecute seems to have solved this.