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 {
|
||||||
struct wl_signal new_output;
|
struct wl_signal new_output;
|
||||||
struct wl_signal view_map;
|
struct wl_signal view_map;
|
||||||
|
struct wl_signal request_active_output;
|
||||||
} events;
|
} events;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool desktop_init(struct kiwmi_desktop *desktop, struct wlr_renderer *renderer);
|
bool desktop_init(struct kiwmi_desktop *desktop, struct wlr_renderer *renderer);
|
||||||
void desktop_fini(struct kiwmi_desktop *desktop);
|
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 */
|
#endif /* KIWMI_DESKTOP_DESKTOP_H */
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct kiwmi_object {
|
||||||
} events;
|
} events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void *luaK_toudata(lua_State *L, int ud, const char *tname);
|
||||||
int luaK_kiwmi_object_gc(lua_State *L);
|
int luaK_kiwmi_object_gc(lua_State *L);
|
||||||
struct kiwmi_object *luaK_get_kiwmi_object(
|
struct kiwmi_object *luaK_get_kiwmi_object(
|
||||||
struct kiwmi_lua *lua,
|
struct kiwmi_lua *lua,
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/types/wlr_data_device.h>
|
#include <wlr/types/wlr_data_device.h>
|
||||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||||
|
@ -22,7 +23,10 @@
|
||||||
|
|
||||||
#include "desktop/layer_shell.h"
|
#include "desktop/layer_shell.h"
|
||||||
#include "desktop/output.h"
|
#include "desktop/output.h"
|
||||||
|
#include "desktop/view.h"
|
||||||
#include "desktop/xdg_shell.h"
|
#include "desktop/xdg_shell.h"
|
||||||
|
#include "input/cursor.h"
|
||||||
|
#include "input/input.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
bool
|
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.new_output);
|
||||||
wl_signal_init(&desktop->events.view_map);
|
wl_signal_init(&desktop->events.view_map);
|
||||||
|
wl_signal_init(&desktop->events.request_active_output);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -76,3 +81,37 @@ desktop_fini(struct kiwmi_desktop *desktop)
|
||||||
{
|
{
|
||||||
wlr_output_layout_destroy(desktop->output_layout);
|
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);
|
layer_surface->namespace);
|
||||||
|
|
||||||
if (!layer_surface->output) {
|
if (!layer_surface->output) {
|
||||||
// TODO: assign active output
|
struct kiwmi_server *server =
|
||||||
wlr_log(WLR_ERROR, "TODO: assign active output");
|
wl_container_of(desktop, server, desktop);
|
||||||
struct kiwmi_output *output;
|
layer_surface->output = desktop_active_output(server)->wlr_output;
|
||||||
wl_list_for_each (output, &desktop->outputs, link) {
|
|
||||||
layer_surface->output = output->wlr_output;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct kiwmi_layer *layer = malloc(sizeof(*layer));
|
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
|
static void
|
||||||
kiwmi_server_on_view_notify(struct wl_listener *listener, void *data)
|
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;
|
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
|
static int
|
||||||
l_kiwmi_server_on_view(lua_State *L)
|
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[] = {
|
static const luaL_Reg kiwmi_server_events[] = {
|
||||||
{"keyboard", l_kiwmi_server_on_keyboard},
|
{"keyboard", l_kiwmi_server_on_keyboard},
|
||||||
{"output", l_kiwmi_server_on_output},
|
{"output", l_kiwmi_server_on_output},
|
||||||
|
{"request_active_output", l_kiwmi_server_on_request_active_output},
|
||||||
{"view", l_kiwmi_server_on_view},
|
{"view", l_kiwmi_server_on_view},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,22 @@
|
||||||
#include "luak/kiwmi_server.h"
|
#include "luak/kiwmi_server.h"
|
||||||
#include "luak/kiwmi_view.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
|
int
|
||||||
luaK_kiwmi_object_gc(lua_State *L)
|
luaK_kiwmi_object_gc(lua_State *L)
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,6 +58,13 @@ Get the view at a specified position.
|
||||||
A new keyboard got attached.
|
A new keyboard got attached.
|
||||||
Callback receives a reference to the keyboard.
|
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
|
#### output
|
||||||
|
|
||||||
A new output got attached.
|
A new output got attached.
|
||||||
|
|
Loading…
Reference in a new issue