Scroll erratic with touchscreen LVGL Version 8 & 9

I have implemented LVGL on a Raspberry Pi 3B+ using the latest master from the Linux framebuffer repository and also 8.3. The Pi has an HDMI touchscreen attached. I added a cursor to the touch screen and it works fine. However, when a scrollable list is displayed (from the demos) scrolling does not work properly. I can drag the lines a little bit then they pop back to their more-or-less original position. The code below is the read callback.
I can’t find any information as to exactly what I should be returning as far as state. As I said, dragging a cursor around the screen works just fine.

    indev_touchpad = lv_indev_create();
    lv_indev_set_type(indev_touchpad, LV_INDEV_TYPE_POINTER);
    lv_indev_set_display(indev_touchpad, disp);
    lv_indev_set_read_cb(indev_touchpad, touchscreen_read);

    lv_obj_t *cursor_img = lv_img_create(lv_scr_act());
    lv_img_set_src(cursor_img, LV_SYMBOL_PLUS);
    lv_indev_set_cursor(indev_touchpad, cursor_img);	

void touchscreen_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
static int32_t last_x = 0;
static int32_t last_y = 0;
static int xpos = -1;
static int ypos = -1;

    data->state = LV_INDEV_STATE_RELEASED;
	
	bool inPacket = false;
	do
	{
		while(libevdev_has_event_pending(dev))
		{
			//printf("Pending...\r\n");
			inPacket = true;
			struct input_event ev;
			read_event(dev, &ev);
			//printf("Type: %d (%s)\r\n", ev.type, eventType(ev.type));
			if(ev.type == EV_MSC) 
			{
				//printf("    Code: %02x (%s)\r\n", ev.code, codeMsc(ev.code));
				//printf("    Value: %d\r\n", ev.value);
			}
			else if (ev.type != 0) 
			{
				//printf("    Code: %02X (%s)\r\n", ev.code, codeType(ev.code));
				//printf("    Value: %d\r\n", ev.value);
				switch( ev.code )
				{
					case ABS_MT_POSITION_X:
						xpos = ev.value;
						break;
					case ABS_MT_POSITION_Y:
						ypos = ev.value;
						break;
					case BTN_TOUCH:
						touchscreen_pressed = ev.value;
						break;
				}
			}
				
			if (ev.type == SYN_REPORT)
			{
				if (touchscreen_pressed > 0 )
				{
					data->state = LV_INDEV_STATE_PRESSED;
					if (xpos >= 0 )
						last_x = xpos;
					
					if (ypos >= 0 )
						last_y = 599 - ypos;

					xpos = -1;
					ypos = -1;
					inPacket = false;
				}
				//printf("REPORT: %d %d %d\n", last_x, last_y, touchscreen_pressed);
				//printf("\r\n");
			}
		}
	} while (inPacket);
	data->point.x = last_x;
	data->point.y = 599 - last_y;
	//printf("Read: %d %d\n", last_x, last_y);
}

It’s because of the while loops you have in your indev callback. collect once and return the results. If you sit there and keep on collecting touch input and the function doesn’t return then LVGL is not going to be able to update based on the touches received.

You also don’t want to make any assumptions like setting the state to released. You should save a copy of the last state and the last coords and if no touch is detected then change the state to released but leave the coords alone and let the function return.

Try something more along these lines

lv_indev_data_t last_received_touch;
last_received_touch.state=LV_INDEV_STATE_RELEASED;
last_received_touch.point.x = -1;
last_received_touch.point.y = -1;


void touchscreen_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
    static int xpos = -1;
    static int ypos = -1;

	while (libevdev_has_event_pending(dev)) {
		//printf("Pending...\r\n");
		struct input_event ev;

		read_event(dev, &ev);
		//printf("Type: %d (%s)\r\n", ev.type, eventType(ev.type));
		if(ev.type == EV_MSC) {
			//printf("    Code: %02x (%s)\r\n", ev.code, codeMsc(ev.code));
			//printf("    Value: %d\r\n", ev.value);
		}
		else if (ev.type != 0) {
			//printf("    Code: %02X (%s)\r\n", ev.code, codeType(ev.code));
			//printf("    Value: %d\r\n", ev.value);
			switch( ev.code ) {
				case ABS_MT_POSITION_X:
					xpos = ev.value;
					break;
				case ABS_MT_POSITION_Y:
					ypos = ev.value;
					break;
				case BTN_TOUCH:
					touchscreen_pressed = ev.value;
					break;
			}

			if ((xpos >= 0) && (ypos >= 0) && touchscreen_pressed) {
			    break;
			}
		}
		
		if (ev.type == SYN_REPORT) {
		    break;
		}
	}
	if (touchscreen_pressed > 0 ) {
		last_received_touch.state = LV_INDEV_STATE_PRESSED;
		if (xpos >= 0 ) {
			last_received_touch.point.x = xpos;
		}
		if (ypos >= 0 ) {
			last_received_touch.point.y = 599 - ypos;
		}
	} else {
	    last_received_touch.state = LV_INDEV_STATE_RELEASED;
	}

	data->state = last_received_touch.state;
	data->point.x = last_received_touch.point.x;
	data->point.y = last_received_touch.point.y;
}

I am not that proficient in C code but that should give you the basic idea of how to go about it.

Oh and you don’t need this either.

    lv_indev_set_cursor(indev_touchpad, cursor_img);	

I found a reference to EVDEV and the following solved the problem. No need for my own driver.

lv_indev_t * indev_ptr = lv_evdev_create(LV_INDEV_TYPE_POINTER, “/dev/input/event0”);