kiwmi_output:usable_area() and :on("usable_area_change")

This commit is contained in:
tiosgz 2021-08-11 18:31:25 +00:00
parent b6e3492234
commit a5e82d083c
5 changed files with 127 additions and 0 deletions

View file

@ -9,6 +9,7 @@
#define KIWMI_DESKTOP_OUTPUT_H
#include <wayland-server.h>
#include <wlr/types/wlr_box.h>
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;
};

View file

@ -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;

View file

@ -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);
}

View file

@ -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},
};

View file

@ -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.