From a5e82d083c610422a42021f516b527cfce008660 Mon Sep 17 00:00:00 2001 From: tiosgz Date: Wed, 11 Aug 2021 18:31:25 +0000 Subject: [PATCH] kiwmi_output:usable_area() and :on("usable_area_change") --- include/desktop/output.h | 3 ++ kiwmi/desktop/layer_shell.c | 6 +++ kiwmi/desktop/output.c | 4 ++ kiwmi/luak/kiwmi_output.c | 105 ++++++++++++++++++++++++++++++++++++ lua_docs.md | 9 ++++ 5 files changed, 127 insertions(+) diff --git a/include/desktop/output.h b/include/desktop/output.h index bd280d5..1397f1c 100644 --- a/include/desktop/output.h +++ b/include/desktop/output.h @@ -9,6 +9,7 @@ #define KIWMI_DESKTOP_OUTPUT_H #include +#include struct kiwmi_output { struct wl_list link; @@ -20,10 +21,12 @@ struct kiwmi_output { struct wl_listener mode; struct wl_list layers[4]; // struct kiwmi_layer_surface::link + struct wlr_box usable_area; struct { struct wl_signal destroy; struct wl_signal resize; + struct wl_signal usable_area_change; } events; }; diff --git a/kiwmi/desktop/layer_shell.c b/kiwmi/desktop/layer_shell.c index 0f8139e..2d0f47e 100644 --- a/kiwmi/desktop/layer_shell.c +++ b/kiwmi/desktop/layer_shell.c @@ -301,6 +301,12 @@ arrange_layers(struct kiwmi_output *output) } } + if (memcmp(&usable_area, &output->usable_area, sizeof(output->usable_area)) + != 0) { + memcpy(&output->usable_area, &usable_area, sizeof(output->usable_area)); + wl_signal_emit(&output->events.usable_area_change, output); + } + struct kiwmi_desktop *desktop = output->desktop; struct kiwmi_server *server = wl_container_of(desktop, server, desktop); struct kiwmi_seat *seat = server->input.seat; diff --git a/kiwmi/desktop/output.c b/kiwmi/desktop/output.c index 9192024..a602e2b 100644 --- a/kiwmi/desktop/output.c +++ b/kiwmi/desktop/output.c @@ -219,6 +219,9 @@ output_create(struct wlr_output *wlr_output, struct kiwmi_desktop *desktop) output->wlr_output = wlr_output; output->desktop = desktop; + output->usable_area.width = wlr_output->width; + output->usable_area.height = wlr_output->height; + output->frame.notify = output_frame_notify; wl_signal_add(&wlr_output->events.frame, &output->frame); @@ -280,6 +283,7 @@ new_output_notify(struct wl_listener *listener, void *data) wl_signal_init(&output->events.destroy); wl_signal_init(&output->events.resize); + wl_signal_init(&output->events.usable_area_change); wl_signal_emit(&desktop->events.new_output, output); } diff --git a/kiwmi/luak/kiwmi_output.c b/kiwmi/luak/kiwmi_output.c index 8c3b7f6..8cd69ac 100644 --- a/kiwmi/luak/kiwmi_output.c +++ b/kiwmi/luak/kiwmi_output.c @@ -116,6 +116,35 @@ l_kiwmi_output_size(lua_State *L) return 2; } +static int +l_kiwmi_output_usable_area(lua_State *L) +{ + struct kiwmi_object *obj = + *(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output"); + + if (!obj->valid) { + return luaL_error(L, "kiwmi_output no longer valid"); + } + + struct kiwmi_output *output = obj->object; + + lua_newtable(L); + + lua_pushinteger(L, output->usable_area.x); + lua_setfield(L, -2, "x"); + + lua_pushinteger(L, output->usable_area.y); + lua_setfield(L, -2, "y"); + + lua_pushinteger(L, output->usable_area.width); + lua_setfield(L, -2, "width"); + + lua_pushinteger(L, output->usable_area.height); + lua_setfield(L, -2, "height"); + + return 1; +} + static const luaL_Reg kiwmi_output_methods[] = { {"auto", l_kiwmi_output_auto}, {"move", l_kiwmi_output_move}, @@ -123,6 +152,7 @@ static const luaL_Reg kiwmi_output_methods[] = { {"on", luaK_callback_register_dispatch}, {"pos", l_kiwmi_output_pos}, {"size", l_kiwmi_output_size}, + {"usable_area", l_kiwmi_output_usable_area}, {NULL, NULL}, }; @@ -192,6 +222,50 @@ kiwmi_output_on_resize_notify(struct wl_listener *listener, void *data) } } +static void +kiwmi_output_on_usable_area_change_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_output *output = data; + + lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref); + + lua_newtable(L); + + lua_pushcfunction(L, luaK_kiwmi_output_new); + lua_pushlightuserdata(L, server->lua); + lua_pushlightuserdata(L, output); + + if (lua_pcall(L, 2, 1, 0)) { + wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); + lua_pop(L, 1); + return; + } + + lua_setfield(L, -2, "output"); + + lua_pushinteger(L, output->usable_area.x); + lua_setfield(L, -2, "x"); + + lua_pushinteger(L, output->usable_area.y); + lua_setfield(L, -2, "y"); + + lua_pushinteger(L, output->usable_area.width); + lua_setfield(L, -2, "width"); + + lua_pushinteger(L, output->usable_area.height); + lua_setfield(L, -2, "height"); + + if (lua_pcall(L, 1, 0, 0)) { + wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); + lua_pop(L, 1); + } +} + static int l_kiwmi_output_on_destroy(lua_State *L) { @@ -252,9 +326,40 @@ l_kiwmi_output_on_resize(lua_State *L) return 0; } +static int +l_kiwmi_output_on_usable_area_change(lua_State *L) +{ + struct kiwmi_object *obj = + *(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_output"); + luaL_checktype(L, 2, LUA_TFUNCTION); + + if (!obj->valid) { + return luaL_error(L, "kiwmi_output no longer valid"); + } + + struct kiwmi_output *output = obj->object; + struct kiwmi_desktop *desktop = output->desktop; + struct kiwmi_server *server = wl_container_of(desktop, server, desktop); + + lua_pushcfunction(L, luaK_kiwmi_lua_callback_new); + lua_pushlightuserdata(L, server); + lua_pushvalue(L, 2); + lua_pushlightuserdata(L, kiwmi_output_on_usable_area_change_notify); + lua_pushlightuserdata(L, &output->events.usable_area_change); + 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_output_events[] = { {"destroy", l_kiwmi_output_on_destroy}, {"resize", l_kiwmi_output_on_resize}, + {"usable_area_change", l_kiwmi_output_on_usable_area_change}, {NULL, NULL}, }; diff --git a/lua_docs.md b/lua_docs.md index 7dc7930..264a906 100644 --- a/lua_docs.md +++ b/lua_docs.md @@ -225,6 +225,10 @@ Returns two parameters: `x` and `y`. Get the size of the output. Returns two parameters: `width` and `height`. +#### output:usable_area() + +Returns a table containing the `x`, `y`, `width` and `height` of the output's usable area, relative to the output's top left corner. + ### Events #### destroy @@ -237,6 +241,11 @@ Callback receives the output. The output is being resized. Callback receives a table containing the `output`, the new `width`, and the new `height`. +#### usable_area_change + +The usable area of this output has changed, e.g. because the output was resized or the bars around it changed. +Callback receives a table containing the `output` and the new `x`, `y`, `width` and `height`. + ## kiwmi_renderer Represents a rendering context, to draw on the output.