AtlatestRepositorysigil-wm

sigil-wm / tree / src / clayers.h

1/* SPDX-License-Identifier: BSD-3-Clause
2 * Layer role facts and explicit configuration. No arrangement or focus rules. */
3static void layer_presentation(struct view *view, bool presented, uint32_t sequence) {
4 pid_t pid = 0;
5 wl_client_get_credentials(wl_resource_get_client(view->layer->resource), &pid, NULL, NULL);
6 struct output *output = view->layer->output ? view->layer->output->data : NULL;
7 view->layer_presented = presented;
8 EVENT(128, view->id, pid, presented, output ? output->id : 0, sequence);
9}
10static void layer_output_present(struct output *output, struct wlr_output_event_present *event) {
11 if (!event->presented || output->server->lock_state) return;
12 struct view *view;
13 wl_list_for_each(view, &output->server->views, link) {
14 if (view->layer && view->layer->output == output->native && view->mapped &&
15 view->tree->node.enabled && !view->layer_presented && view->layer_present_armed &&
16 (int32_t)(event->commit_seq - view->layer_present_commit) >= 0)
17 layer_presentation(view, true, event->commit_seq);
18 }
20static void layer_state(struct view *view) {
21 struct wlr_layer_surface_v1 *native = view->layer;
22 const struct wlr_layer_surface_v1_state *state = native->initialized ? &native->current : &native->pending;
23 struct output *output = native->output ? native->output->data : NULL;
24 EVENT(19, view->id, output ? output->id : 0, state->layer, state->anchor,
25 state->exclusive_zone, state->desired_width, state->desired_height,
26 state->margin.top, state->margin.right, state->margin.bottom, state->margin.left,
27 state->keyboard_interactive, state->exclusive_edge, native->initialized);
29static void layer_map(struct wl_listener *listener, void *data) {
30 (void)data;
31 struct view *view = wl_container_of(listener, view, map);
32 view->mapped = true;
33 layer_state(view);
34 EVENT(11, view->id);
36static void layer_commit(struct wl_listener *listener, void *data) {
37 (void)data;
38 struct view *view = wl_container_of(listener, view, commit);
39 if (view->layer->initial_commit || view->layer->current.committed) layer_state(view);
40 struct wlr_surface *surface = view_surface(view);
41 if (surface->current.width != view->committed.width || surface->current.height != view->committed.height ||
42 view_serial(view) != view->committed_serial) {
43 view->committed = (struct wlr_box){0, 0, surface->current.width, surface->current.height};
44 view->committed_serial = view_serial(view);
45 EVENT(18, view->id, 0, 0, surface->current.width, surface->current.height, view->committed_serial);
46 }
47 check_plan(view->server);
49static void layer_destroy(struct wl_listener *listener, void *data) {
50 (void)data;
51 struct view *view = wl_container_of(listener, view, destroy);
52 struct server *server = view->server;
53 if (server->focus == view->id) set_focus(server, 0);
54 wl_list_remove(&view->map.link);
55 wl_list_remove(&view->unmap.link);
56 wl_list_remove(&view->commit.link);
57 wl_list_remove(&view->destroy.link);
58 wl_list_remove(&view->role_popup.link);
59 wl_list_remove(&view->role_output_destroy.link);
60 wl_list_remove(&view->link);
61 view->layer->data = NULL;
62 discard_saved(view);
63 wlr_scene_node_destroy(&view->tree->node);
64 EVENT(13, view->id);
65 atomic_fetch_sub(&bridge.objects, 1);
66 free(view);
67 check_plan(server);
69static void layer_output_destroy(struct wl_listener *listener, void *data) {
70 (void)data;
71 struct view *view = wl_container_of(listener, view, role_output_destroy);
72 wlr_layer_surface_v1_destroy(view->layer);
74static void assign_layer_output(struct view *view, struct output *output) {
75 wl_list_remove(&view->role_output_destroy.link);
76 view->layer->output = output->native;
77 listen(&output->native->events.destroy, &view->role_output_destroy, layer_output_destroy);
79static void layer_popup(struct wl_listener *listener, void *data) {
80 struct view *view = wl_container_of(listener, view, role_popup);
81 new_popup(&view->server->new_popup, data);
83static void new_layer(struct wl_listener *listener, void *data) {
84 struct server *server = wl_container_of(listener, server, new_layer);
85 struct wlr_layer_surface_v1 *native = data;
86 struct output *output = native->output ? native->output->data :
87 find_output(server, server->default_layer_output);
88 /* wlroots requires an output before this callback returns. The fallback
89 * handle is supplied explicitly by Sigil before role admission. */
90 if (!output) {
91 wlr_layer_surface_v1_destroy(native);
92 return;
93 }
94 struct view *view = calloc(1, sizeof(*view));
95 if (!view) {
96 wl_client_post_no_memory(wl_resource_get_client(native->resource));
97 return;
98 }
99 view->server = server;
100 view->layer = native;
101 view->id = ++server->next_id;
102 view->tree = wlr_scene_tree_create(server->normal);
103 view->live = view->tree ? wlr_scene_subsurface_tree_create(view->tree, native->surface) : NULL;
104 if (!view->live) {
105 if (view->tree) { discard_saved(view); wlr_scene_node_destroy(&view->tree->node); }
106 free(view);
107 wl_client_post_no_memory(wl_resource_get_client(native->resource));
108 return;
109 }
110 wl_list_init(&view->role_output_destroy.link);
111 native->data = view;
112 assign_layer_output(view, output);
113 view->tree->node.data = view;
114 wlr_scene_node_set_enabled(&view->tree->node, false);
115 wl_list_insert(&server->views, &view->link);
116 listen(&native->surface->events.map, &view->map, layer_map);
117 listen(&native->surface->events.unmap, &view->unmap, view_unmap);
118 listen(&native->surface->events.commit, &view->commit, layer_commit);
119 listen(&native->events.destroy, &view->destroy, layer_destroy);
120 listen(&native->events.new_popup, &view->role_popup, layer_popup);
121 atomic_fetch_add(&bridge.objects, 1);
122 EVENT(10, view->id, 1);
123 layer_presentation(view, false, 0);
124 refresh_inhibitors(server);
125 object_text(view->id, 16, native->namespace);
126 layer_state(view);
128static bool configure_layer(struct server *server, int64_t *words) {
129 struct view *view = find_view(server, words[1]);
130 struct output *output = find_output(server, words[2]);
131 if (!view || !view->layer || !view->layer->initialized || !output ||
132 words[3] < 1 || words[3] > 16384 || words[4] < 1 || words[4] > 16384) return false;
133 assign_layer_output(view, output);
134 view->width = words[3];
135 view->height = words[4];
136 view->serial = wlr_layer_surface_v1_configure(view->layer, words[3], words[4]);
137 return true;