Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wayland on embedded device does not respond to touch events #240

Open
gorogoro2 opened this issue Oct 28, 2022 · 9 comments
Open

wayland on embedded device does not respond to touch events #240

gorogoro2 opened this issue Oct 28, 2022 · 9 comments
Labels

Comments

@gorogoro2
Copy link
Contributor

Hi all,

I have an application writen with lvgl using the wayland driver that is working fine when I use the performance monitoring on (mem and fps).
However when I remove it (the monitoring stuff) the application does not respond to the touch events properly:

#define LV_USE_PERF_MONITOR 0
#define LV_USE_MEM_MONITOR 0

I did an experiment and on the main loop I added the following line:
lv_obj_invalidate(lv_scr_act()); and with this the input events are working fine.

Of course this is not a solution.

Is there any way to handle this?

Thank you.

@kisvegabor
Copy link
Member

@simplejack-src @WallaceIT could you take a look at this issue?

@WallaceIT
Copy link
Contributor

Hi @gorogoro2 ,

how are you calling the wayland cycle function? I.e, are you using or not the lv_wayland_timer_handler function?
If yes, have you set up the poll functionality to catch Wayland events in real time?

@gorogoro2
Copy link
Contributor Author

Hi @WallaceIT

Yes, I am using the lv_wayland_timer_handler(); instead of lv_task_handler(); on my loop.

Regarding this statment:

If yes, have you set up the poll functionality to catch Wayland events in real time?

I don't know what are you talking about, probably not. What poll functionality should I setup?

Are you talking about this README.md sleep/wait thing?

Event-driven timer handler
Set LV_WAYLAND_TIMER_HANDLER in lv_drv_conf.h and call lv_wayland_timer_handler() in your timer loop (in place of lv_timer_handler()).

You can now sleep/wait until the next timer/event is ready, e.g.:

/* [After initialization and display creation] */
#include <limits.h>
#include <errno.h>
#include <poll.h>

struct pollfd pfd;
uint32_t time_till_next;
int sleep;

pfd.fd = lv_wayland_get_fd();
pfd.events = POLLIN;

while (1) {
    /* Handle any Wayland/LVGL timers/events */
    time_till_next = lv_wayland_timer_handler();

    /* Run until the last window closes */
    if (!lv_wayland_window_is_open(NULL)) {
        break;
    }

    /* Wait for something interesting to happen */
    if (time_till_next == LV_NO_TIMER_READY) {
        sleep = -1;
    } else if (time_till_next > INT_MAX) {
        sleep = INT_MAX;
    } else {
       sleep = time_till_next;
    }

    while ((poll(&pfd, 1, sleep) < 0) && (errno == EINTR));
}

@gorogoro2
Copy link
Contributor Author

Update,

I have added the following code to my loop:

    auto time_till_next = lv_wayland_timer_handler();
    auto sleep = time_till_next;
    /* Wait for something interesting to happen */
    if (time_till_next == LV_NO_TIMER_READY) {
        sleep = -1;
    } else if (time_till_next > INT_MAX) {
        sleep = INT_MAX;
    }

    while ((poll(&pfd, 1, sleep) < 0) && (errno == EINTR));

Before I only had:

    lv_wayland_timer_handler();

And this way things work a little better, however far from perfect. Sometimes it just doesn't get the touch event. But when I turn on monitoring:

#define LV_USE_PERF_MONITOR 0

Everything is fine again.

@WallaceIT
Copy link
Contributor

Hi,

please consider that the Wayland input events are received as part of the lv_wayland_timer_handler() function; if this is not called at the right moment, some events might get lost.

Referring to the example in the README, the right moment is detected using the poll function in conjuntion with time_till_next, that is:

  • if no input events are received, next call will be performed when the LVGL core will need to execute something (as the value returned by lv_wayland_timer_handler() is derived from LVGL core, not the Wayland driver)
  • if an input event is received, the poll() function will return as soon as this happens (and in the example reported in the README, this causes an immediate call to lv_wayland_timer_handler()).

After the snippet you posted, what's in your event loop? Ideally, you should have nothing more than that. In particular, no call to lv_timer_handler() shall be performed, as this function is already called as part of lv_wayland_timer_handler().

@gorogoro2
Copy link
Contributor Author

Hi Thank you for your reply.

That's my event loop. I have nothing more there. It runs every 15ms and I'm not calling lv_timer_handler().
could it be the buffer thing being discussed on other issues?

@WallaceIT
Copy link
Contributor

Hi @gorogoro2,

I don't think it's related, as the input events are processed regardless of the status of the input events.

Here is an example main.c, please check if anything rings a bell while I investigate:

#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/wayland/wayland.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>

#include <limits.h>
#include <errno.h>
#include <poll.h>

int main(void)
{
    struct pollfd pfd;
    uint32_t time_till_next;
    int sleep;

    /*LittlevGL init*/
    lv_init();

    /*Wayland init*/
    lv_wayland_init();

    lv_disp_t * disp = lv_wayland_create_window(1280, 800, "Window Title", NULL);
    lv_disp_set_default(disp);

    /*Create a Demo*/
    lv_demo_widgets();

    pfd.fd = lv_wayland_get_fd();
    pfd.events = POLLIN;

    /*Handle LitlevGL tasks (tickless mode)*/
    while (lv_wayland_window_is_open(NULL)) {

        /* Handle any Wayland/LVGL timers/events */
        time_till_next = lv_wayland_timer_handler();

        /* Wait for something interesting to happen */
        if (time_till_next == LV_NO_TIMER_READY) {
            sleep = -1;
        } else if (time_till_next > INT_MAX) {
            sleep = INT_MAX;
        } else {
           sleep = time_till_next;
        }

        while ((poll(&pfd, 1, sleep) < 0) && (errno == EINTR));
    }

    return 0;
}

/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void)
{
    static uint64_t start_ms = 0;
    if(start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}

@symfund
Copy link

symfund commented Nov 22, 2022

Probably, #240 is related with my earlier reported ticket #225

@stale
Copy link

stale bot commented Apr 20, 2023

This issue or pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Apr 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants