1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#include "util.h"
#include "wl.h"
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_xdg_shell.h>
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);
}
}
|