AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Layer role facts and explicit configuration. No arrangement or focus rules. */3
static 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
}10
static 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
}19
}20
static 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);28
}29
static 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);35
}36
static 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);48
}49
static 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);68
}69
static 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);73
}74
static 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);78
}79
static 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);82
}83
static 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 fallback89
* 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);127
}128
static 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;138
}