#include "util.h" #include "wl.h" #include #include static struct montis_server *server_from_ctx(void *ctx) { struct montis_server *server = wl_container_of(ctx, server, world); return server; } static struct montis_toplevel *toplevel_at(struct montis_server *server, double lx, double ly) { double sx = 0.0; double sy = 0.0; struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->tree.node, lx, ly, &sx, &sy); if (node == NULL || node->type != WLR_SCENE_NODE_BUFFER) { return NULL; } struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node); struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer); if (!scene_surface) { return NULL; } struct wlr_scene_tree *tree = node->parent; while (tree != NULL && tree->node.data == NULL) { tree = tree->node.parent; } return tree ? tree->node.data : NULL; } void *arkworld_toplevel_at(void *ctx, double lx, double ly) { if (!ctx) { return NULL; } struct montis_server *server = server_from_ctx(ctx); return toplevel_at(server, lx, ly); } void arkworld_get_toplevel_position(void *toplevel, double *x, double *y) { if (!toplevel || !x || !y) { return; } struct montis_toplevel *tl = toplevel; *x = tl->scene_tree->node.x; *y = tl->scene_tree->node.y; } void arkworld_set_toplevel_position(void *toplevel, double x, double y) { if (!toplevel) { return; } struct montis_toplevel *tl = toplevel; wlr_scene_node_set_position(&tl->scene_tree->node, (int)x, (int)y); } void arkworld_get_toplevel_geometry(void *toplevel, double *x, double *y, double *w, double *h) { if (!toplevel || !x || !y || !w || !h) { return; } struct montis_toplevel *tl = toplevel; struct wlr_box geo_box; wlr_xdg_surface_get_geometry(tl->xdg_toplevel->base, &geo_box); *x = tl->scene_tree->node.x; *y = tl->scene_tree->node.y; *w = geo_box.width; *h = geo_box.height; } void arkworld_set_toplevel_geometry(void *toplevel, double x, double y, double w, double h) { if (!toplevel) { return; } struct montis_toplevel *tl = toplevel; wlr_scene_node_set_position(&tl->scene_tree->node, (int)x, (int)y); wlr_xdg_toplevel_set_size(tl->xdg_toplevel, (int)w, (int)h); } void arkworld_warp_cursor(void *ctx, double lx, double ly) { if (!ctx) { return; } struct montis_server *server = server_from_ctx(ctx); wlr_cursor_warp(server->cursor, NULL, lx, ly); } void arkworld_focus_toplevel(void *toplevel) { if (!toplevel) { return; } struct montis_toplevel *tl = toplevel; struct montis_server *server = tl->server; struct wlr_seat *seat = server->seat; struct wlr_surface *surface = tl->xdg_toplevel->base->surface; struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface; if (prev_surface == surface) { return; } if (prev_surface) { struct wlr_xdg_toplevel *prev_toplevel = wlr_xdg_toplevel_try_from_wlr_surface(prev_surface); if (prev_toplevel != NULL) { wlr_xdg_toplevel_set_activated(prev_toplevel, false); } } struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat); wlr_scene_node_raise_to_top(&tl->scene_tree->node); wl_list_remove(&tl->link); wl_list_insert(&server->toplevels, &tl->link); wlr_xdg_toplevel_set_activated(tl->xdg_toplevel, true); if (keyboard != NULL) { wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers); } }