#10139·lvgl

Slider will return to 0 after touch realse with Wayland

Author: Lander112233Created May 19, 2026Updated Sep 12, 2026
Labelsdriverswidget-slider

LVGL version

V9.5.0

Platform

Linux Embedded Operating System

What happened?

When create a slider, with Wayland, after touch realse, slider value will return to 0 immediately.

The reason is in Wayland. When touch up, with using gesture recogntion, the touch point will be set to 0 in function touch_handle_up in file lvgl/src/drivers/wayland/lv_wayland_touch.c:

/* Create a released event */ #if LV_USE_GESTURE_RECOGNITION uint8_t i = tdata->event_cnt; tdata->touches[i].point.x = 0; tdata->touches[i].point.y = 0; tdata->touches[i].id = id; tdata->touches[i].timestamp = time; tdata->touches[i].state = LV_INDEV_STATE_RELEASED;

tdata->event_cnt++; #else tdata->state = LV_INDEV_STATE_RELEASED; #endif

After touch realse, event LV_EVENT_RELEASED will be generated; function update_knob_pos will be called to read the point value, which has already been set to 0 by touch_handle_up. So, the value using function lv_slider_get_value to read will be 0, which is used by slider_event_cb.

  1. touch realase
  2. generate event LV_EVENT_RELEASED
  3. In function lv_slider_event, call update_knob_pos due to event LV_EVENT_RELEASED
  4. update_knob_pos read the point value, and send the event LV_EVENT_VALUE_CHANGED
  5. slider_event_cb read the point value using lv_slider_get_value, due to the event LV_EVENT_VALUE_CHANGED
  6. the point value is 0, set by touch_handle_up

I have to deal the event LV_EVENT_RELEASED specificly in slider_event_cb, to avoid the 0.

I wonder, why set the touch point to 0 when touch realse? It looks like that gesture recogntion algorithm doesn't need the last point must be 0.

(I have to dump the last 0 point in ordinary touch read, or it will cause the touch point "jump" to 0)

How to reproduce?

static lv_obj_t *slider_label;

static void slider_event_cb(lv_event_t *e) { lv_obj_t *slider = static_cast<lv_obj_t *>(lv_event_get_target(e)); int32_t value = lv_slider_get_value(slider);

char buf[8];
snprintf(buf, sizeof(buf), "%d %%", static_cast<int>(value));
lv_label_set_text(slider_label, buf);

lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
printf("Slider value changed to: %d\n", value);

}

void lv_slider_test(void) { lv_obj_t *slider = lv_slider_create(lv_scr_act());

lv_obj_set_size(slider, 200, 10);
lv_obj_center(slider);

lv_slider_set_range(slider, 0, 100);
lv_slider_set_value(slider, 30, LV_ANIM_ON);

lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

slider_label = lv_label_create(lv_scr_act());
lv_label_set_text(slider_label, "30 %");
lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

}

int main(void) { LOG_initLogger(LOG_Level::Debug, "/var/log", 10, 5, LOG_OutputMode::All); LOG_DEBUG("Hello, A Value is {}", 1);

lv_init();
lv_drv_hal_init();

lv_slider_test();

while (1) {
    lv_timer_handler();
    std::this_thread::sleep_for(std::chrono::microseconds(5000));
}

return 0;

}