XuNeo / luavgl

lua + lvgl = luavgl An optimized lvgl Lua binding
MIT License
57 stars 13 forks source link

lv_disp expected, got no value #22

Closed jonsmirl closed 4 months ago

jonsmirl commented 4 months ago

Introduce the problem

I am using the lvgl-v8 branch on an ESP32 which doesn't have v9 available yet. Most things are working, adding this failed: local scr = lvgl.disp.get_scr_act()

I traced down to this: luavgl_disp_t *v = luaL_checkudata(L, idx, "lv_disp"); p is null, so it calls typeerror()

luavgl_disp_init() is getting called and it makes the metatable.

/init.lua:1: bad argument #1 to 'get_scr_act' (lv_disp expected, got no value)
stack traceback:
    [C]: in field 'get_scr_act'
    /init.lua:1: in main chunk
    [C]: in ?

Proposal

No response

jonsmirl commented 4 months ago

I am using Lua 5.3 luavgl_disp_get() makes a new display entry during initialization.

It is calling luavgl_to_disp(L, 1); in luavgl_disp_get_scr_act() then void *p = lua_touserdata(L, ud); is null because there is no entry for 1.

When I trace into lua_rawset(L, LUA_REGISTRYINDEX); in luavgl_disp_get() it is using an index of -13000.

XuNeo commented 4 months ago

Hi, Could you try #23?

For the error you found, it's because lvgl.disp.get_scr_act() expects the first argument to be a display. Since it's common to use NULL in C to get default display, I added below code to make lua behaves similar to C.

https://github.com/XuNeo/luavgl/compare/gesture-examples?expand=1#diff-38da6e19c0633f5b6b8afcf645c50f851150f1ee1678a6a5b291e45b72c3ffd0R51-R54

The example in PR has been tested from my side and is working. Please do notice the scr_act object needs manually to add CLICKABLE flag in lvgl v8.

jonsmirl commented 4 months ago

Thanks for the help, I am making progress scr works now and I get gesture events.

local indev = lvgl.indev.get_act() My indev is nil, maybe a similar issue?

luavgl_indev_get() finds the pointer, but the variable is nil.

XuNeo commented 4 months ago

Have you tried to get indev_act in event callback?

This is the recommended method, since indev_act in lvgl is a global var that should only be used during input event processing.


scr:onevent(lvgl.EVENT.GESTURE, function(obj, code)
    local indev = lvgl.indev.get_act()
    print("gesture dir: ", indev:get_gesture_dir())
end)
jonsmirl commented 4 months ago

Thanks again, that works. One more thing to include in your example

scr:onevent(lvgl.EVENT.GESTURE, function (obj, code)
    local indev = lvgl.indev.get_act()
    print("gesture dir: ", indev:get_gesture_dir())
    indev:wait_release()
end)

You will likely want that wait_release() at the end of a gesture otherwise it will activate whatever widget you are over when your release the gesture.