diff --git a/include/input/cursor.h b/include/input/cursor.h index 1271e6f..540cc3d 100644 --- a/include/input/cursor.h +++ b/include/input/cursor.h @@ -44,6 +44,7 @@ struct kiwmi_cursor { struct wl_signal button_down; struct wl_signal button_up; struct wl_signal motion; + struct wl_signal scroll; } events; }; @@ -59,6 +60,13 @@ struct kiwmi_cursor_motion_event { double newy; }; +struct kiwmi_cursor_scroll_event { + const char *device_name; + bool is_vertical; + double length; + bool handled; +}; + struct kiwmi_cursor *cursor_create( struct kiwmi_server *server, struct wlr_output_layout *output_layout); diff --git a/kiwmi/input/cursor.c b/kiwmi/input/cursor.c index c591013..dd801b1 100644 --- a/kiwmi/input/cursor.c +++ b/kiwmi/input/cursor.c @@ -210,13 +210,24 @@ cursor_axis_notify(struct wl_listener *listener, void *data) struct kiwmi_input *input = &server->input; struct wlr_event_pointer_axis *event = data; - wlr_seat_pointer_notify_axis( - input->seat->seat, - event->time_msec, - event->orientation, - event->delta, - event->delta_discrete, - event->source); + struct kiwmi_cursor_scroll_event new_event = { + .device_name = event->device->name, + .is_vertical = event->orientation == WLR_AXIS_ORIENTATION_VERTICAL, + .length = event->delta, + .handled = false, + }; + + wl_signal_emit(&cursor->events.scroll, &new_event); + + if (!new_event.handled) { + wlr_seat_pointer_notify_axis( + input->seat->seat, + event->time_msec, + event->orientation, + event->delta, + event->delta_discrete, + event->source); + } } static void @@ -277,6 +288,7 @@ cursor_create( wl_signal_init(&cursor->events.button_down); wl_signal_init(&cursor->events.button_up); wl_signal_init(&cursor->events.motion); + wl_signal_init(&cursor->events.scroll); return cursor; } diff --git a/kiwmi/luak/kiwmi_cursor.c b/kiwmi/luak/kiwmi_cursor.c index 2a1e0c7..97eb159 100644 --- a/kiwmi/luak/kiwmi_cursor.c +++ b/kiwmi/luak/kiwmi_cursor.c @@ -162,6 +162,36 @@ kiwmi_cursor_on_motion_notify(struct wl_listener *listener, void *data) } } +static void +kiwmi_cursor_on_scroll_notify(struct wl_listener *listener, void *data) +{ + struct kiwmi_lua_callback *lc = wl_container_of(listener, lc, listener); + struct kiwmi_server *server = lc->server; + lua_State *L = server->lua->L; + struct kiwmi_cursor_scroll_event *event = data; + + lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref); + + lua_newtable(L); + + lua_pushstring(L, event->device_name); + lua_setfield(L, -2, "device"); + + lua_pushnumber(L, event->is_vertical); + lua_setfield(L, -2, "vertical"); + + lua_pushnumber(L, event->length); + lua_setfield(L, -2, "length"); + + if (lua_pcall(L, 1, 1, 0)) { + wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); + lua_pop(L, 1); + } + + event->handled |= lua_toboolean(L, -1); + lua_pop(L, 1); +} + static int l_kiwmi_cursor_on_button_down(lua_State *L) { @@ -237,10 +267,36 @@ l_kiwmi_cursor_on_motion(lua_State *L) return 0; } +static int +l_kiwmi_cursor_on_scroll(lua_State *L) +{ + struct kiwmi_object *obj = + *(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_cursor"); + luaL_checktype(L, 2, LUA_TFUNCTION); + + struct kiwmi_cursor *cursor = obj->object; + struct kiwmi_server *server = cursor->server; + + lua_pushcfunction(L, luaK_kiwmi_lua_callback_new); + lua_pushlightuserdata(L, server); + lua_pushvalue(L, 2); + lua_pushlightuserdata(L, kiwmi_cursor_on_scroll_notify); + lua_pushlightuserdata(L, &cursor->events.scroll); + lua_pushlightuserdata(L, obj); + + if (lua_pcall(L, 5, 0, 0)) { + wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); + return 0; + } + + return 0; +} + static const luaL_Reg kiwmi_cursor_events[] = { {"button_down", l_kiwmi_cursor_on_button_down}, {"button_up", l_kiwmi_cursor_on_button_up}, {"motion", l_kiwmi_cursor_on_motion}, + {"scroll", l_kiwmi_cursor_on_scroll}, {NULL, NULL}, }; diff --git a/lua_docs.md b/lua_docs.md index 1de2b7e..098000c 100644 --- a/lua_docs.md +++ b/lua_docs.md @@ -149,6 +149,14 @@ The compositor will not forward it to the view under the cursor. The cursor got moved. Callback receives a table containing `oldx`, `oldy`, `newx`, and `newy`. +#### scroll + +Something was scrolled. +The callback receives a table containing `device` with the device name, `vertical` indicating whether it was a vertical or horizontal scroll, and `length` with the length of the vector (negative for left of up scrolls). + +The callback is supposed to return `true` if the event was handled. +The compositor will not forward it to the view under the cursor. + ## kiwmi_keyboard A handle to a keyboard.