aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Alexander Orzechowski <alex@ozal.ski>2023-11-23 10:09:48 -0500
committerLibravatar Kirill Primak <vyivel@eclair.cafe>2024-01-18 18:36:54 +0300
commit5b8b505af5d5925ae9e617ee8f3c7a0f9c43409d (patch)
treef420022ad3a48215f9182505c0060d91edcd848e
parentIntroduce sway_text_node (diff)
downloadsway-5b8b505af5d5925ae9e617ee8f3c7a0f9c43409d.tar.gz
sway-5b8b505af5d5925ae9e617ee8f3c7a0f9c43409d.tar.zst
sway-5b8b505af5d5925ae9e617ee8f3c7a0f9c43409d.zip
input: Query scene graph for relevant surface/node intersections
-rw-r--r--include/sway/scene_descriptor.h3
-rw-r--r--include/sway/tree/container.h13
-rw-r--r--include/sway/tree/root.h4
-rw-r--r--sway/input/cursor.c184
-rw-r--r--sway/tree/container.c265
-rw-r--r--sway/tree/root.c21
-rw-r--r--sway/tree/view.c7
7 files changed, 89 insertions, 408 deletions
diff --git a/include/sway/scene_descriptor.h b/include/sway/scene_descriptor.h
index 057993ec..8af81219 100644
--- a/include/sway/scene_descriptor.h
+++ b/include/sway/scene_descriptor.h
@@ -12,6 +12,9 @@
12 12
13enum sway_scene_descriptor_type { 13enum sway_scene_descriptor_type {
14 SWAY_SCENE_DESC_BUFFER_TIMER, 14 SWAY_SCENE_DESC_BUFFER_TIMER,
15 SWAY_SCENE_DESC_NON_INTERACTIVE,
16 SWAY_SCENE_DESC_CONTAINER,
17 SWAY_SCENE_DESC_VIEW,
15 SWAY_SCENE_DESC_DRAG_ICON, 18 SWAY_SCENE_DESC_DRAG_ICON,
16}; 19};
17 20
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index ee22a0d0..6f72439c 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -172,19 +172,6 @@ void container_begin_destroy(struct sway_container *con);
172struct sway_container *container_find_child(struct sway_container *container, 172struct sway_container *container_find_child(struct sway_container *container,
173 bool (*test)(struct sway_container *view, void *data), void *data); 173 bool (*test)(struct sway_container *view, void *data), void *data);
174 174
175/**
176 * Find a container at the given coordinates. Returns the surface and
177 * surface-local coordinates of the given layout coordinates if the container
178 * is a view and the view contains a surface at those coordinates.
179 */
180struct sway_container *container_at(struct sway_workspace *workspace,
181 double lx, double ly, struct wlr_surface **surface,
182 double *sx, double *sy);
183
184struct sway_container *tiling_container_at(
185 struct sway_node *parent, double lx, double ly,
186 struct wlr_surface **surface, double *sx, double *sy);
187
188void container_for_each_child(struct sway_container *container, 175void container_for_each_child(struct sway_container *container,
189 void (*f)(struct sway_container *container, void *data), void *data); 176 void (*f)(struct sway_container *container, void *data), void *data);
190 177
diff --git a/include/sway/tree/root.h b/include/sway/tree/root.h
index 0aae8938..003606aa 100644
--- a/include/sway/tree/root.h
+++ b/include/sway/tree/root.h
@@ -35,6 +35,10 @@ struct sway_root {
35 // staging node will be visible. 35 // staging node will be visible.
36 struct wlr_scene_tree *staging; 36 struct wlr_scene_tree *staging;
37 37
38 // tree containing all layers the compositor will render. Cursor handling
39 // will end up iterating this tree.
40 struct wlr_scene_tree *layer_tree;
41
38 struct { 42 struct {
39 struct wlr_scene_tree *tiling; 43 struct wlr_scene_tree *tiling;
40 struct wlr_scene_tree *floating; 44 struct wlr_scene_tree *floating;
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 107424c9..79373e40 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -37,43 +37,6 @@ static uint32_t get_current_time_msec(void) {
37 return now.tv_sec * 1000 + now.tv_nsec / 1000000; 37 return now.tv_sec * 1000 + now.tv_nsec / 1000000;
38} 38}
39 39
40static struct wlr_surface *layer_surface_at(struct sway_output *output,
41 struct wl_list *layer, double ox, double oy, double *sx, double *sy) {
42 struct sway_layer_surface *sway_layer;
43 wl_list_for_each_reverse(sway_layer, layer, link) {
44 double _sx = ox - sway_layer->geo.x;
45 double _sy = oy - sway_layer->geo.y;
46 struct wlr_surface *sub = wlr_layer_surface_v1_surface_at(
47 sway_layer->layer_surface, _sx, _sy, sx, sy);
48 if (sub) {
49 return sub;
50 }
51 }
52 return NULL;
53}
54
55static bool surface_is_xdg_popup(struct wlr_surface *surface) {
56 struct wlr_xdg_surface *xdg_surface =
57 wlr_xdg_surface_try_from_wlr_surface(surface);
58 return xdg_surface != NULL && xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP &&
59 xdg_surface->popup != NULL;
60}
61
62static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
63 struct wl_list *layer, double ox, double oy, double *sx, double *sy) {
64 struct sway_layer_surface *sway_layer;
65 wl_list_for_each_reverse(sway_layer, layer, link) {
66 double _sx = ox - sway_layer->geo.x;
67 double _sy = oy - sway_layer->geo.y;
68 struct wlr_surface *sub = wlr_layer_surface_v1_surface_at(
69 sway_layer->layer_surface, _sx, _sy, sx, sy);
70 if (sub && surface_is_xdg_popup(sub)) {
71 return sub;
72 }
73 }
74 return NULL;
75}
76
77/** 40/**
78 * Returns the node at the cursor's position. If there is a surface at that 41 * Returns the node at the cursor's position. If there is a surface at that
79 * location, it is stored in **surface (it may not be a view). 42 * location, it is stored in **surface (it may not be a view).
@@ -81,116 +44,79 @@ static struct wlr_surface *layer_surface_popup_at(struct sway_output *output,
81struct sway_node *node_at_coords( 44struct sway_node *node_at_coords(
82 struct sway_seat *seat, double lx, double ly, 45 struct sway_seat *seat, double lx, double ly,
83 struct wlr_surface **surface, double *sx, double *sy) { 46 struct wlr_surface **surface, double *sx, double *sy) {
84 // find the output the cursor is on 47 struct wlr_scene_node *scene_node = NULL;
85 struct wlr_output *wlr_output = wlr_output_layout_output_at(
86 root->output_layout, lx, ly);
87 if (wlr_output == NULL) {
88 return NULL;
89 }
90 struct sway_output *output = wlr_output->data;
91 if (!output || !output->enabled) {
92 // output is being destroyed or is being enabled
93 return NULL;
94 }
95 double ox = lx, oy = ly;
96 wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);
97 48
98 // layer surfaces on the overlay layer are rendered on top 49 struct wlr_scene_node *node;
99 if ((*surface = layer_surface_at(output, 50 wl_list_for_each_reverse(node, &root->layer_tree->children, link) {
100 &output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], 51 struct wlr_scene_tree *layer = wlr_scene_tree_from_node(node);
101 ox, oy, sx, sy))) {
102 return NULL;
103 }
104 52
105 // check for unmanaged views 53 bool non_interactive = scene_descriptor_try_get(&layer->node,
106#if HAVE_XWAYLAND 54 SWAY_SCENE_DESC_NON_INTERACTIVE);
107 struct wl_list *unmanaged = &root->xwayland_unmanaged; 55 if (non_interactive) {
108 struct sway_xwayland_unmanaged *unmanaged_surface; 56 continue;
109 wl_list_for_each_reverse(unmanaged_surface, unmanaged, link) {
110 struct wlr_xwayland_surface *xsurface =
111 unmanaged_surface->wlr_xwayland_surface;
112
113 double _sx = lx - unmanaged_surface->lx;
114 double _sy = ly - unmanaged_surface->ly;
115 if (wlr_surface_point_accepts_input(xsurface->surface, _sx, _sy)) {
116 *surface = xsurface->surface;
117 *sx = _sx;
118 *sy = _sy;
119 return NULL;
120 } 57 }
121 }
122#endif
123 58
124 if (root->fullscreen_global) { 59 scene_node = wlr_scene_node_at(&layer->node, lx, ly, sx, sy);
125 // Try fullscreen container 60 if (scene_node) {
126 struct sway_container *con = tiling_container_at( 61 break;
127 &root->fullscreen_global->node, lx, ly, surface, sx, sy);
128 if (con) {
129 return &con->node;
130 } 62 }
131 return NULL;
132 } 63 }
133 64
134 // find the focused workspace on the output for this seat 65 if (scene_node) {
135 struct sway_workspace *ws = output_get_active_workspace(output); 66 // determine what wlr_surface we clicked on
136 if (!ws) { 67 if (scene_node->type == WLR_SCENE_NODE_BUFFER) {
137 return NULL; 68 struct wlr_scene_buffer *scene_buffer =
138 } 69 wlr_scene_buffer_from_node(scene_node);
70 struct wlr_scene_surface *scene_surface =
71 wlr_scene_surface_try_from_buffer(scene_buffer);
72
73 if (scene_surface) {
74 *surface = scene_surface->surface;
75 }
76 }
139 77
140 if (ws->fullscreen) { 78 // determine what container we clicked on
141 // Try transient containers 79 struct wlr_scene_node *current = scene_node;
142 for (int i = 0; i < ws->floating->length; ++i) { 80 while (true) {
143 struct sway_container *floater = ws->floating->items[i]; 81 struct sway_container *con = scene_descriptor_try_get(current,
144 if (container_is_transient_for(floater, ws->fullscreen)) { 82 SWAY_SCENE_DESC_CONTAINER);
145 struct sway_container *con = tiling_container_at( 83 if (!con) {
146 &floater->node, lx, ly, surface, sx, sy); 84 struct sway_view *view = scene_descriptor_try_get(current,
147 if (con) { 85 SWAY_SCENE_DESC_VIEW);
86 if (view) {
87 con = view->container;
88 }
89 }
90
91 if (con) {
92 if (!con->view || con->view->surface) {
148 return &con->node; 93 return &con->node;
149 } 94 }
150 } 95 }
96
97 if (!current->parent) {
98 break;
99 }
100
101 current = &current->parent->node;
151 } 102 }
152 // Try fullscreen container
153 struct sway_container *con =
154 tiling_container_at(&ws->fullscreen->node, lx, ly, surface, sx, sy);
155 if (con) {
156 return &con->node;
157 }
158 return NULL;
159 }
160 if ((*surface = layer_surface_popup_at(output,
161 &output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
162 ox, oy, sx, sy))) {
163 return NULL;
164 }
165 if ((*surface = layer_surface_popup_at(output,
166 &output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM],
167 ox, oy, sx, sy))) {
168 return NULL;
169 }
170 if ((*surface = layer_surface_popup_at(output,
171 &output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND],
172 ox, oy, sx, sy))) {
173 return NULL;
174 }
175 if ((*surface = layer_surface_at(output,
176 &output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
177 ox, oy, sx, sy))) {
178 return NULL;
179 } 103 }
180 104
181 struct sway_container *c; 105 // if we aren't on a container, determine what workspace we are on
182 if ((c = container_at(ws, lx, ly, surface, sx, sy))) { 106 struct wlr_output *wlr_output = wlr_output_layout_output_at(
183 return &c->node; 107 root->output_layout, lx, ly);
108 if (wlr_output == NULL) {
109 return NULL;
184 } 110 }
185 111
186 if ((*surface = layer_surface_at(output, 112 struct sway_output *output = wlr_output->data;
187 &output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], 113 if (!output || !output->enabled) {
188 ox, oy, sx, sy))) { 114 // output is being destroyed or is being enabled
189 return NULL; 115 return NULL;
190 } 116 }
191 if ((*surface = layer_surface_at(output, 117
192 &output->shell_layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], 118 struct sway_workspace *ws = output_get_active_workspace(output);
193 ox, oy, sx, sy))) { 119 if (!ws) {
194 return NULL; 120 return NULL;
195 } 121 }
196 122
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 307bf963..8fca6a12 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -16,6 +16,7 @@
16#include "sway/input/input-manager.h" 16#include "sway/input/input-manager.h"
17#include "sway/input/seat.h" 17#include "sway/input/seat.h"
18#include "sway/ipc-server.h" 18#include "sway/ipc-server.h"
19#include "sway/scene_descriptor.h"
19#include "sway/output.h" 20#include "sway/output.h"
20#include "sway/server.h" 21#include "sway/server.h"
21#include "sway/surface.h" 22#include "sway/surface.h"
@@ -94,6 +95,11 @@ struct sway_container *container_create(struct sway_view *view) {
94 c->border.right = alloc_rect_node(c->border.tree, &failed); 95 c->border.right = alloc_rect_node(c->border.tree, &failed);
95 } 96 }
96 97
98 if (!failed && !scene_descriptor_assign(&c->scene_tree->node,
99 SWAY_SCENE_DESC_CONTAINER, c)) {
100 failed = true;
101 }
102
97 if (failed) { 103 if (failed) {
98 wlr_scene_node_destroy(&c->scene_tree->node); 104 wlr_scene_node_destroy(&c->scene_tree->node);
99 free(c); 105 free(c);
@@ -239,265 +245,6 @@ struct sway_container *container_find_child(struct sway_container *container,
239 return NULL; 245 return NULL;
240} 246}
241 247
242static struct sway_container *surface_at_view(struct sway_container *con, double lx, double ly,
243 struct wlr_surface **surface, double *sx, double *sy) {
244 if (!sway_assert(con->view, "Expected a view")) {
245 return NULL;
246 }
247 struct sway_view *view = con->view;
248 double view_sx = lx - con->surface_x + view->geometry.x;
249 double view_sy = ly - con->surface_y + view->geometry.y;
250
251 double _sx, _sy;
252 struct wlr_surface *_surface = NULL;
253 switch (view->type) {
254#if HAVE_XWAYLAND
255 case SWAY_VIEW_XWAYLAND:
256 _surface = wlr_surface_surface_at(view->surface,
257 view_sx, view_sy, &_sx, &_sy);
258 break;
259#endif
260 case SWAY_VIEW_XDG_SHELL:
261 _surface = wlr_xdg_surface_surface_at(
262 view->wlr_xdg_toplevel->base,
263 view_sx, view_sy, &_sx, &_sy);
264 break;
265 }
266 if (_surface) {
267 *sx = _sx;
268 *sy = _sy;
269 *surface = _surface;
270 return con;
271 }
272 return NULL;
273}
274
275/**
276 * container_at for a container with layout L_TABBED.
277 */
278static struct sway_container *container_at_tabbed(struct sway_node *parent,
279 double lx, double ly,
280 struct wlr_surface **surface, double *sx, double *sy) {
281 struct wlr_box box;
282 node_get_box(parent, &box);
283 if (lx < box.x || lx > box.x + box.width ||
284 ly < box.y || ly > box.y + box.height) {
285 return NULL;
286 }
287 struct sway_seat *seat = input_manager_current_seat();
288 list_t *children = node_get_children(parent);
289 if (!children->length) {
290 return NULL;
291 }
292
293 // Tab titles
294 int title_height = container_titlebar_height();
295 if (ly < box.y + title_height) {
296 int tab_width = box.width / children->length;
297 int child_index = (lx - box.x) / tab_width;
298 if (child_index >= children->length) {
299 child_index = children->length - 1;
300 }
301 struct sway_container *child = children->items[child_index];
302 return child;
303 }
304
305 // Surfaces
306 struct sway_node *current = seat_get_active_tiling_child(seat, parent);
307 return current ? tiling_container_at(current, lx, ly, surface, sx, sy) : NULL;
308}
309
310/**
311 * container_at for a container with layout L_STACKED.
312 */
313static struct sway_container *container_at_stacked(struct sway_node *parent,
314 double lx, double ly,
315 struct wlr_surface **surface, double *sx, double *sy) {
316 struct wlr_box box;
317 node_get_box(parent, &box);
318 if (lx < box.x || lx > box.x + box.width ||
319 ly < box.y || ly > box.y + box.height) {
320 return NULL;
321 }
322 struct sway_seat *seat = input_manager_current_seat();
323 list_t *children = node_get_children(parent);
324
325 // Title bars
326 int title_height = container_titlebar_height();
327 if (title_height > 0) {
328 int child_index = (ly - box.y) / title_height;
329 if (child_index < children->length) {
330 struct sway_container *child = children->items[child_index];
331 return child;
332 }
333 }
334
335 // Surfaces
336 struct sway_node *current = seat_get_active_tiling_child(seat, parent);
337 return current ? tiling_container_at(current, lx, ly, surface, sx, sy) : NULL;
338}
339
340/**
341 * container_at for a container with layout L_HORIZ or L_VERT.
342 */
343static struct sway_container *container_at_linear(struct sway_node *parent,
344 double lx, double ly,
345 struct wlr_surface **surface, double *sx, double *sy) {
346 list_t *children = node_get_children(parent);
347 for (int i = 0; i < children->length; ++i) {
348 struct sway_container *child = children->items[i];
349 struct sway_container *container =
350 tiling_container_at(&child->node, lx, ly, surface, sx, sy);
351 if (container) {
352 return container;
353 }
354 }
355 return NULL;
356}
357
358static struct sway_container *floating_container_at(double lx, double ly,
359 struct wlr_surface **surface, double *sx, double *sy) {
360 // For outputs with floating containers that overhang the output bounds,
361 // those at the end of the output list appear on top of floating
362 // containers from other outputs, so iterate the list in reverse.
363 for (int i = root->outputs->length - 1; i >= 0; --i) {
364 struct sway_output *output = root->outputs->items[i];
365 for (int j = 0; j < output->workspaces->length; ++j) {
366 struct sway_workspace *ws = output->workspaces->items[j];
367 if (!workspace_is_visible(ws)) {
368 continue;
369 }
370 // Items at the end of the list are on top, so iterate the list in
371 // reverse.
372 for (int k = ws->floating->length - 1; k >= 0; --k) {
373 struct sway_container *floater = ws->floating->items[k];
374 struct sway_container *container =
375 tiling_container_at(&floater->node, lx, ly, surface, sx, sy);
376 if (container) {
377 return container;
378 }
379 }
380 }
381 }
382 return NULL;
383}
384
385static struct sway_container *view_container_content_at(struct sway_node *parent,
386 double lx, double ly,
387 struct wlr_surface **surface, double *sx, double *sy) {
388 if (!sway_assert(node_is_view(parent), "Expected a view")) {
389 return NULL;
390 }
391
392 struct sway_container *container = parent->sway_container;
393 struct wlr_box box = {
394 .x = container->pending.content_x,
395 .y = container->pending.content_y,
396 .width = container->pending.content_width,
397 .height = container->pending.content_height,
398 };
399
400 if (wlr_box_contains_point(&box, lx, ly)) {
401 surface_at_view(parent->sway_container, lx, ly, surface, sx, sy);
402 return container;
403 }
404
405 return NULL;
406}
407
408static struct sway_container *view_container_at(struct sway_node *parent,
409 double lx, double ly,
410 struct wlr_surface **surface, double *sx, double *sy) {
411 if (!sway_assert(node_is_view(parent), "Expected a view")) {
412 return NULL;
413 }
414
415 struct sway_container *container = parent->sway_container;
416 struct wlr_box box = {
417 .x = container->pending.x,
418 .y = container->pending.y,
419 .width = container->pending.width,
420 .height = container->pending.height,
421 };
422
423 if (wlr_box_contains_point(&box, lx, ly)) {
424 surface_at_view(parent->sway_container, lx, ly, surface, sx, sy);
425 return container;
426 }
427
428 return NULL;
429}
430
431struct sway_container *tiling_container_at(struct sway_node *parent,
432 double lx, double ly,
433 struct wlr_surface **surface, double *sx, double *sy) {
434 if (node_is_view(parent)) {
435 return view_container_at(parent, lx, ly, surface, sx, sy);
436 }
437 if (!node_get_children(parent)) {
438 return NULL;
439 }
440 switch (node_get_layout(parent)) {
441 case L_HORIZ:
442 case L_VERT:
443 return container_at_linear(parent, lx, ly, surface, sx, sy);
444 case L_TABBED:
445 return container_at_tabbed(parent, lx, ly, surface, sx, sy);
446 case L_STACKED:
447 return container_at_stacked(parent, lx, ly, surface, sx, sy);
448 case L_NONE:
449 return NULL;
450 }
451 return NULL;
452}
453
454static bool surface_is_popup(struct wlr_surface *surface) {
455 while (wlr_xdg_surface_try_from_wlr_surface(surface) == NULL) {
456 struct wlr_subsurface *subsurface =
457 wlr_subsurface_try_from_wlr_surface(surface);
458 if (subsurface == NULL) {
459 return false;
460 }
461 surface = subsurface->parent;
462 }
463 struct wlr_xdg_surface *xdg_surface =
464 wlr_xdg_surface_try_from_wlr_surface(surface);
465 return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP && xdg_surface->popup != NULL;
466}
467
468struct sway_container *container_at(struct sway_workspace *workspace,
469 double lx, double ly,
470 struct wlr_surface **surface, double *sx, double *sy) {
471 struct sway_container *c;
472
473 struct sway_seat *seat = input_manager_current_seat();
474 struct sway_container *focus = seat_get_focused_container(seat);
475 bool is_floating = focus && container_is_floating_or_child(focus);
476 // Focused view's popups
477 if (focus && focus->view) {
478 c = surface_at_view(focus, lx, ly, surface, sx, sy);
479 if (c && surface_is_popup(*surface)) {
480 return c;
481 }
482 *surface = NULL;
483 }
484 // Floating
485 if ((c = floating_container_at(lx, ly, surface ,sx ,sy))) {
486 return c;
487 }
488 // Tiling (focused)
489 if (focus && focus->view && !is_floating) {
490 if ((c = view_container_content_at(&focus->node, lx, ly, surface, sx, sy))) {
491 return c;
492 }
493 }
494 // Tiling (non-focused)
495 if ((c = tiling_container_at(&workspace->node, lx, ly, surface, sx, sy))) {
496 return c;
497 }
498 return NULL;
499}
500
501void container_for_each_child(struct sway_container *container, 248void container_for_each_child(struct sway_container *container,
502 void (*f)(struct sway_container *container, void *data), 249 void (*f)(struct sway_container *container, void *data),
503 void *data) { 250 void *data) {
diff --git a/sway/tree/root.c b/sway/tree/root.c
index e4941566..fbdd9a96 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -9,6 +9,7 @@
9#include "sway/input/seat.h" 9#include "sway/input/seat.h"
10#include "sway/ipc-server.h" 10#include "sway/ipc-server.h"
11#include "sway/output.h" 11#include "sway/output.h"
12#include "sway/scene_descriptor.h"
12#include "sway/tree/arrange.h" 13#include "sway/tree/arrange.h"
13#include "sway/tree/container.h" 14#include "sway/tree/container.h"
14#include "sway/tree/root.h" 15#include "sway/tree/root.h"
@@ -44,13 +45,19 @@ struct sway_root *root_create(struct wl_display *wl_display) {
44 45
45 bool failed = false; 46 bool failed = false;
46 root->staging = alloc_scene_tree(&root_scene->tree, &failed); 47 root->staging = alloc_scene_tree(&root_scene->tree, &failed);
47 48 root->layer_tree = alloc_scene_tree(&root_scene->tree, &failed);
48 root->layers.tiling = alloc_scene_tree(&root_scene->tree, &failed); 49
49 root->layers.floating = alloc_scene_tree(&root_scene->tree, &failed); 50 root->layers.tiling = alloc_scene_tree(root->layer_tree, &failed);
50 root->layers.fullscreen = alloc_scene_tree(&root_scene->tree, &failed); 51 root->layers.floating = alloc_scene_tree(root->layer_tree, &failed);
51 root->layers.fullscreen_global = alloc_scene_tree(&root_scene->tree, &failed); 52 root->layers.fullscreen = alloc_scene_tree(root->layer_tree, &failed);
52 root->layers.seat = alloc_scene_tree(&root_scene->tree, &failed); 53 root->layers.fullscreen_global = alloc_scene_tree(root->layer_tree, &failed);
53 root->layers.session_lock = alloc_scene_tree(&root_scene->tree, &failed); 54 root->layers.seat = alloc_scene_tree(root->layer_tree, &failed);
55 root->layers.session_lock = alloc_scene_tree(root->layer_tree, &failed);
56
57 if (!failed && !scene_descriptor_assign(&root->layers.seat->node,
58 SWAY_SCENE_DESC_NON_INTERACTIVE, (void *)1)) {
59 failed = true;
60 }
54 61
55 if (failed) { 62 if (failed) {
56 wlr_scene_node_destroy(&root_scene->tree.node); 63 wlr_scene_node_destroy(&root_scene->tree.node);
diff --git a/sway/tree/view.c b/sway/tree/view.c
index bc968edc..d349e5fa 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -24,6 +24,7 @@
24#include "sway/ipc-server.h" 24#include "sway/ipc-server.h"
25#include "sway/output.h" 25#include "sway/output.h"
26#include "sway/input/seat.h" 26#include "sway/input/seat.h"
27#include "sway/scene_descriptor.h"
27#include "sway/server.h" 28#include "sway/server.h"
28#include "sway/surface.h" 29#include "sway/surface.h"
29#include "sway/tree/arrange.h" 30#include "sway/tree/arrange.h"
@@ -40,6 +41,12 @@ bool view_init(struct sway_view *view, enum sway_view_type type,
40 bool failed = false; 41 bool failed = false;
41 view->scene_tree = alloc_scene_tree(root->staging, &failed); 42 view->scene_tree = alloc_scene_tree(root->staging, &failed);
42 view->content_tree = alloc_scene_tree(view->scene_tree, &failed); 43 view->content_tree = alloc_scene_tree(view->scene_tree, &failed);
44
45 if (!failed && !scene_descriptor_assign(&view->scene_tree->node,
46 SWAY_SCENE_DESC_VIEW, view)) {
47 failed = true;
48 }
49
43 if (failed) { 50 if (failed) {
44 wlr_scene_node_destroy(&view->scene_tree->node); 51 wlr_scene_node_destroy(&view->scene_tree->node);
45 return false; 52 return false;