Add request_active_output event
This commit is contained in:
parent
4bc201754a
commit
1cc4f52a77
7 changed files with 128 additions and 7 deletions
|
@ -29,10 +29,14 @@ struct kiwmi_desktop {
|
|||
struct {
|
||||
struct wl_signal new_output;
|
||||
struct wl_signal view_map;
|
||||
struct wl_signal request_active_output;
|
||||
} events;
|
||||
};
|
||||
|
||||
bool desktop_init(struct kiwmi_desktop *desktop, struct wlr_renderer *renderer);
|
||||
void desktop_fini(struct kiwmi_desktop *desktop);
|
||||
|
||||
struct kiwmi_server;
|
||||
struct kiwmi_output *desktop_active_output(struct kiwmi_server *server);
|
||||
|
||||
#endif /* KIWMI_DESKTOP_DESKTOP_H */
|
||||
|
|
|
@ -37,6 +37,7 @@ struct kiwmi_object {
|
|||
} events;
|
||||
};
|
||||
|
||||
void *luaK_toudata(lua_State *L, int ud, const char *tname);
|
||||
int luaK_kiwmi_object_gc(lua_State *L);
|
||||
struct kiwmi_object *luaK_get_kiwmi_object(
|
||||
struct kiwmi_lua *lua,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <wayland-server.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
|
@ -22,7 +23,10 @@
|
|||
|
||||
#include "desktop/layer_shell.h"
|
||||
#include "desktop/output.h"
|
||||
#include "desktop/view.h"
|
||||
#include "desktop/xdg_shell.h"
|
||||
#include "input/cursor.h"
|
||||
#include "input/input.h"
|
||||
#include "server.h"
|
||||
|
||||
bool
|
||||
|
@ -67,6 +71,7 @@ desktop_init(struct kiwmi_desktop *desktop, struct wlr_renderer *renderer)
|
|||
|
||||
wl_signal_init(&desktop->events.new_output);
|
||||
wl_signal_init(&desktop->events.view_map);
|
||||
wl_signal_init(&desktop->events.request_active_output);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -76,3 +81,37 @@ desktop_fini(struct kiwmi_desktop *desktop)
|
|||
{
|
||||
wlr_output_layout_destroy(desktop->output_layout);
|
||||
}
|
||||
|
||||
struct kiwmi_output *
|
||||
desktop_active_output(struct kiwmi_server *server)
|
||||
{
|
||||
// 1. callback (request_active_output)
|
||||
struct kiwmi_output *output = NULL;
|
||||
wl_signal_emit(&server->desktop.events.request_active_output, &output);
|
||||
|
||||
if (output) {
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
// 2. focused view center
|
||||
if (!wl_list_empty(&server->desktop.views)) {
|
||||
struct kiwmi_view *view;
|
||||
wl_list_for_each (view, &server->desktop.views, link) {
|
||||
break; // get first element of list
|
||||
}
|
||||
|
||||
double lx = view->geom.x + view->geom.width / 2;
|
||||
double ly = view->geom.y + view->geom.height / 2;
|
||||
|
||||
struct wlr_output *wlr_output = wlr_output_layout_output_at(server->desktop.output_layout, lx, ly);
|
||||
return wlr_output->data;
|
||||
}
|
||||
|
||||
// 3. cursor
|
||||
double lx = server->input.cursor->cursor->x;
|
||||
double ly = server->input.cursor->cursor->y;
|
||||
|
||||
struct wlr_output *wlr_output = wlr_output_layout_output_at(server->desktop.output_layout, lx, ly);
|
||||
return wlr_output->data;
|
||||
}
|
||||
|
|
|
@ -351,13 +351,9 @@ layer_shell_new_surface_notify(struct wl_listener *listener, void *data)
|
|||
layer_surface->namespace);
|
||||
|
||||
if (!layer_surface->output) {
|
||||
// TODO: assign active output
|
||||
wlr_log(WLR_ERROR, "TODO: assign active output");
|
||||
struct kiwmi_output *output;
|
||||
wl_list_for_each (output, &desktop->outputs, link) {
|
||||
layer_surface->output = output->wlr_output;
|
||||
break;
|
||||
}
|
||||
struct kiwmi_server *server =
|
||||
wl_container_of(desktop, server, desktop);
|
||||
layer_surface->output = desktop_active_output(server)->wlr_output;
|
||||
}
|
||||
|
||||
struct kiwmi_layer *layer = malloc(sizeof(*layer));
|
||||
|
|
|
@ -305,6 +305,39 @@ kiwmi_server_on_output_notify(struct wl_listener *listener, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kiwmi_server_on_request_active_output_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);
|
||||
if (lua_pcall(L, 0, 1, 0)) {
|
||||
wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lua_isnil(L, -1)) {
|
||||
struct kiwmi_object *obj;
|
||||
struct kiwmi_object **objp;
|
||||
if (!(objp = luaK_toudata(L, -1, "kiwmi_output"))) {
|
||||
wlr_log(WLR_ERROR, "kiwmi_output expected, got %s", luaL_typename(L, -1));
|
||||
return;
|
||||
}
|
||||
|
||||
obj = *objp;
|
||||
|
||||
if (!obj->valid) {
|
||||
wlr_log(WLR_ERROR, "kiwmi_output no longer valid");
|
||||
return;
|
||||
}
|
||||
|
||||
*output = obj->object;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kiwmi_server_on_view_notify(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
@ -378,6 +411,30 @@ l_kiwmi_server_on_output(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
l_kiwmi_server_on_request_active_output(lua_State *L)
|
||||
{
|
||||
struct kiwmi_object *obj =
|
||||
*(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server");
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
|
||||
struct kiwmi_server *server = obj->object;
|
||||
|
||||
lua_pushcfunction(L, luaK_kiwmi_lua_callback_new);
|
||||
lua_pushlightuserdata(L, server);
|
||||
lua_pushvalue(L, 2);
|
||||
lua_pushlightuserdata(L, kiwmi_server_on_request_active_output_notify);
|
||||
lua_pushlightuserdata(L, &server->desktop.events.request_active_output);
|
||||
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 int
|
||||
l_kiwmi_server_on_view(lua_State *L)
|
||||
{
|
||||
|
@ -405,6 +462,7 @@ l_kiwmi_server_on_view(lua_State *L)
|
|||
static const luaL_Reg kiwmi_server_events[] = {
|
||||
{"keyboard", l_kiwmi_server_on_keyboard},
|
||||
{"output", l_kiwmi_server_on_output},
|
||||
{"request_active_output", l_kiwmi_server_on_request_active_output},
|
||||
{"view", l_kiwmi_server_on_view},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
|
|
@ -22,6 +22,22 @@
|
|||
#include "luak/kiwmi_server.h"
|
||||
#include "luak/kiwmi_view.h"
|
||||
|
||||
void *
|
||||
luaK_toudata(lua_State *L, int ud, const char *tname)
|
||||
{
|
||||
void *p = lua_touserdata(L, ud);
|
||||
if (p != NULL) { /* value is a userdata? */
|
||||
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
|
||||
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
|
||||
lua_pop(L, 2); /* remove both metatables */
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
luaK_kiwmi_object_gc(lua_State *L)
|
||||
{
|
||||
|
|
|
@ -58,6 +58,13 @@ Get the view at a specified position.
|
|||
A new keyboard got attached.
|
||||
Callback receives a reference to the keyboard.
|
||||
|
||||
#### request_active_output
|
||||
|
||||
Called when the active output needs to be requested (for example because a layer-shell surface needs to be positioned).
|
||||
Callback receives nothing and optionally returns a kiwmi_output.
|
||||
|
||||
If this isn't set or returns `nil`, the compositor defaults to the output the focused view is on, and if there is no view, the output the mouse is on.
|
||||
|
||||
#### output
|
||||
|
||||
A new output got attached.
|
||||
|
|
Loading…
Reference in a new issue