mirror of
https://github.com/swaywm/sway.git
synced 2024-11-14 06:24:20 +01:00
Merge eadc380a30
into 4cfcb3643b
This commit is contained in:
commit
5539422c5b
@ -84,9 +84,16 @@ struct sway_cursor {
|
||||
|
||||
struct sway_node;
|
||||
|
||||
struct wlr_scene_node *scene_node_at_coords(
|
||||
double lx, double ly, double *sx, double *sy);
|
||||
|
||||
struct wlr_surface *surface_try_from_scene_node(struct wlr_scene_node *node);
|
||||
|
||||
struct sway_node *sway_node_try_from_scene_node(struct wlr_scene_node *node,
|
||||
double lx, double ly);
|
||||
|
||||
struct sway_node *node_at_coords(
|
||||
struct sway_seat *seat, double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy);
|
||||
double lx, double ly, struct wlr_surface **surface, double *sx, double *sy);
|
||||
|
||||
void sway_cursor_destroy(struct sway_cursor *cursor);
|
||||
struct sway_cursor *sway_cursor_create(struct sway_seat *seat);
|
||||
|
@ -36,9 +36,6 @@ struct sway_layer_popup {
|
||||
|
||||
struct sway_output;
|
||||
|
||||
struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
||||
struct wlr_surface *surface);
|
||||
|
||||
void arrange_layers(struct sway_output *output);
|
||||
|
||||
#endif
|
||||
|
@ -10,6 +10,14 @@
|
||||
#define _SWAY_SCENE_DESCRIPTOR_H
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
|
||||
struct sway_view;
|
||||
|
||||
// used for SWAY_SCENE_DESC_POPUP
|
||||
struct sway_popup_desc {
|
||||
struct wlr_scene_node *relative;
|
||||
struct sway_view *view;
|
||||
};
|
||||
|
||||
enum sway_scene_descriptor_type {
|
||||
SWAY_SCENE_DESC_BUFFER_TIMER,
|
||||
SWAY_SCENE_DESC_NON_INTERACTIVE,
|
||||
@ -24,10 +32,23 @@ enum sway_scene_descriptor_type {
|
||||
bool scene_descriptor_assign(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type, void *data);
|
||||
|
||||
bool scene_descriptor_reassign(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type, void *data);
|
||||
|
||||
void *scene_descriptor_try_get(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type);
|
||||
|
||||
void scene_descriptor_destroy(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type);
|
||||
|
||||
/*
|
||||
* Searches the scene node and all its parents for this scene descriptor.
|
||||
*
|
||||
* Note that while searching, SWAY_SCENE_DESC_POPUP types will start tracking
|
||||
* its relative node. With popups, they are part of a seperate layer in the scene
|
||||
* graph, but that's irrelavent to users of this function.
|
||||
*/
|
||||
void *scene_descriptor_find(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type);
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
#endif
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
#include "sway/scene_descriptor.h"
|
||||
|
||||
struct sway_container;
|
||||
struct sway_xdg_decoration;
|
||||
@ -185,11 +186,6 @@ struct sway_xwayland_unmanaged {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct sway_popup_desc {
|
||||
struct wlr_scene_node *relative;
|
||||
struct sway_view *view;
|
||||
};
|
||||
|
||||
struct sway_xdg_popup {
|
||||
struct sway_view *view;
|
||||
|
||||
|
@ -621,7 +621,7 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding)
|
||||
|| binding->type == BINDING_MOUSECODE) {
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_node *node = node_at_coords(seat,
|
||||
struct sway_node *node = node_at_coords(
|
||||
seat->cursor->cursor->x, seat->cursor->cursor->y,
|
||||
&surface, &sx, &sy);
|
||||
if (node && node->type == N_CONTAINER) {
|
||||
|
@ -20,39 +20,6 @@
|
||||
#include "sway/tree/arrange.h"
|
||||
#include "sway/tree/workspace.h"
|
||||
|
||||
struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
|
||||
struct wlr_surface *surface) {
|
||||
struct wlr_layer_surface_v1 *layer;
|
||||
do {
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
// Topmost layer surface
|
||||
if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) {
|
||||
return layer;
|
||||
}
|
||||
// Layer subsurface
|
||||
if (wlr_subsurface_try_from_wlr_surface(surface)) {
|
||||
surface = wlr_surface_get_root_surface(surface);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Layer surface popup
|
||||
struct wlr_xdg_surface *xdg_surface = NULL;
|
||||
if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(surface)) &&
|
||||
xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP && xdg_surface->popup != NULL) {
|
||||
if (!xdg_surface->popup->parent) {
|
||||
return NULL;
|
||||
}
|
||||
surface = wlr_surface_get_root_surface(xdg_surface->popup->parent);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Return early if the surface is not a layer/xdg_popup/sub surface
|
||||
return NULL;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
static void arrange_surface(struct sway_output *output, const struct wlr_box *full_area,
|
||||
struct wlr_box *usable_area, struct wlr_scene_tree *tree, bool exclusive) {
|
||||
struct wlr_scene_node *node;
|
||||
|
@ -152,20 +152,9 @@ static void send_frame_done_iterator(struct wlr_scene_buffer *buffer,
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_scene_node *current = &buffer->node;
|
||||
while (true) {
|
||||
struct sway_view *view = scene_descriptor_try_get(current,
|
||||
SWAY_SCENE_DESC_VIEW);
|
||||
if (view) {
|
||||
view_max_render_time = view->max_render_time;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!current->parent) {
|
||||
break;
|
||||
}
|
||||
|
||||
current = ¤t->parent->node;
|
||||
struct sway_view *view = scene_descriptor_find(&buffer->node, SWAY_SCENE_DESC_VIEW);
|
||||
if (view) {
|
||||
view_max_render_time = view->max_render_time;
|
||||
}
|
||||
|
||||
int delay = data->msec_until_refresh - output->max_render_time
|
||||
|
@ -38,15 +38,8 @@ static uint32_t get_current_time_msec(void) {
|
||||
return now.tv_sec * 1000 + now.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node at the cursor's position. If there is a surface at that
|
||||
* location, it is stored in **surface (it may not be a view).
|
||||
*/
|
||||
struct sway_node *node_at_coords(
|
||||
struct sway_seat *seat, double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
struct wlr_scene_node *scene_node = NULL;
|
||||
|
||||
struct wlr_scene_node *scene_node_at_coords(
|
||||
double lx, double ly, double *sx, double *sy) {
|
||||
struct wlr_scene_node *node;
|
||||
wl_list_for_each_reverse(node, &root->layer_tree->children, link) {
|
||||
struct wlr_scene_tree *layer = wlr_scene_tree_from_node(node);
|
||||
@ -57,69 +50,58 @@ struct sway_node *node_at_coords(
|
||||
continue;
|
||||
}
|
||||
|
||||
scene_node = wlr_scene_node_at(&layer->node, lx, ly, sx, sy);
|
||||
if (scene_node) {
|
||||
break;
|
||||
struct wlr_scene_node *node = wlr_scene_node_at(&layer->node, lx, ly, sx, sy);
|
||||
if (node) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
if (scene_node) {
|
||||
// determine what wlr_surface we clicked on
|
||||
if (scene_node->type == WLR_SCENE_NODE_BUFFER) {
|
||||
struct wlr_scene_buffer *scene_buffer =
|
||||
wlr_scene_buffer_from_node(scene_node);
|
||||
struct wlr_scene_surface *scene_surface =
|
||||
wlr_scene_surface_try_from_buffer(scene_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (scene_surface) {
|
||||
*surface = scene_surface->surface;
|
||||
}
|
||||
}
|
||||
struct wlr_surface *surface_try_from_scene_node(struct wlr_scene_node *node) {
|
||||
if (!node || node->type != WLR_SCENE_NODE_BUFFER) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// determine what container we clicked on
|
||||
struct wlr_scene_node *current = scene_node;
|
||||
while (true) {
|
||||
struct sway_container *con = scene_descriptor_try_get(current,
|
||||
SWAY_SCENE_DESC_CONTAINER);
|
||||
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 (!con) {
|
||||
struct sway_view *view = scene_descriptor_try_get(current,
|
||||
SWAY_SCENE_DESC_VIEW);
|
||||
if (view) {
|
||||
con = view->container;
|
||||
}
|
||||
}
|
||||
if (scene_surface) {
|
||||
return scene_surface->surface;
|
||||
}
|
||||
|
||||
if (!con) {
|
||||
struct sway_popup_desc *popup =
|
||||
scene_descriptor_try_get(current, SWAY_SCENE_DESC_POPUP);
|
||||
if (popup && popup->view) {
|
||||
con = popup->view->container;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (con && (!con->view || con->view->surface)) {
|
||||
return &con->node;
|
||||
}
|
||||
|
||||
if (scene_descriptor_try_get(current, SWAY_SCENE_DESC_LAYER_SHELL)) {
|
||||
// We don't want to feed through the current workspace on
|
||||
// layer shells
|
||||
struct sway_node *sway_node_try_from_scene_node(struct wlr_scene_node *node,
|
||||
double lx, double ly) {
|
||||
if (node) {
|
||||
struct sway_container *con =
|
||||
scene_descriptor_find(node, SWAY_SCENE_DESC_CONTAINER);
|
||||
if (con) {
|
||||
// If this condition succeeds, the container is currently in the
|
||||
// process of being destroyed. In this case, ignore the container
|
||||
if (con->view && !con->view->surface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &con->node;
|
||||
}
|
||||
|
||||
// if we clicked on a layer shell or unmanaged xwayland we don't
|
||||
// want to return the workspace node.
|
||||
if (scene_descriptor_find(node, SWAY_SCENE_DESC_LAYER_SHELL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if WLR_HAS_XWAYLAND
|
||||
if (scene_descriptor_try_get(current, SWAY_SCENE_DESC_XWAYLAND_UNMANAGED)) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!current->parent) {
|
||||
break;
|
||||
}
|
||||
|
||||
current = ¤t->parent->node;
|
||||
if (scene_descriptor_find(node, SWAY_SCENE_DESC_XWAYLAND_UNMANAGED)) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// if we aren't on a container, determine what workspace we are on
|
||||
@ -143,6 +125,18 @@ struct sway_node *node_at_coords(
|
||||
return &ws->node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node at the cursor's position. If there is a surface at that
|
||||
* location, it is stored in **surface (it may not be a view).
|
||||
*/
|
||||
struct sway_node *node_at_coords(double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
struct wlr_scene_node *scene_node = scene_node_at_coords(lx, ly, sx, sy);
|
||||
*surface = surface_try_from_scene_node(scene_node);
|
||||
|
||||
return sway_node_try_from_scene_node(scene_node, lx, ly);
|
||||
}
|
||||
|
||||
void cursor_rebase(struct sway_cursor *cursor) {
|
||||
uint32_t time_msec = get_current_time_msec();
|
||||
seatop_rebase(cursor->seat, time_msec);
|
||||
@ -305,8 +299,7 @@ void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
||||
if (cursor->active_constraint && device->type == WLR_INPUT_DEVICE_POINTER) {
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
node_at_coords(cursor->seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (cursor->active_constraint->surface != surface) {
|
||||
return;
|
||||
@ -565,7 +558,7 @@ static void handle_tablet_tool_position(struct sway_cursor *cursor,
|
||||
double sx, sy;
|
||||
struct wlr_surface *surface = NULL;
|
||||
struct sway_seat *seat = cursor->seat;
|
||||
node_at_coords(seat, cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
// The logic for whether we should send a tablet event or an emulated pointer
|
||||
// event is tricky. It comes down to:
|
||||
@ -655,8 +648,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
|
||||
|
||||
double sx, sy;
|
||||
struct wlr_surface *surface = NULL;
|
||||
node_at_coords(seat, cursor->cursor->x, cursor->cursor->y,
|
||||
&surface, &sx, &sy);
|
||||
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (cursor->simulating_pointer_from_tool_tip &&
|
||||
event->state == WLR_TABLET_TOOL_TIP_UP) {
|
||||
@ -740,8 +732,7 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
|
||||
double sx, sy;
|
||||
struct wlr_surface *surface = NULL;
|
||||
|
||||
node_at_coords(cursor->seat, cursor->cursor->x, cursor->cursor->y,
|
||||
&surface, &sx, &sy);
|
||||
node_at_coords(cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
// TODO: floating resize should support graphics tablet events
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
|
||||
|
@ -223,7 +223,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_node *node = node_at_coords(seat,
|
||||
struct sway_node *node = node_at_coords(
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (!sway_assert(surface,
|
||||
@ -334,10 +334,12 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
|
||||
// Determine what's under the cursor
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_node *node = node_at_coords(seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
struct wlr_scene_node *scene_node =
|
||||
scene_node_at_coords(cursor->cursor->x, cursor->cursor->y, &sx, &sy);
|
||||
struct wlr_surface *surface = scene_node ? surface_try_from_scene_node(scene_node) : NULL;
|
||||
struct sway_node *node = sway_node_try_from_scene_node(scene_node,
|
||||
cursor->cursor->x, cursor->cursor->y);
|
||||
|
||||
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
||||
node->sway_container : NULL;
|
||||
@ -379,10 +381,10 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
|
||||
}
|
||||
|
||||
// Handle clicking a layer surface and its popups/subsurfaces
|
||||
struct wlr_layer_surface_v1 *layer = NULL;
|
||||
if ((layer = toplevel_layer_surface_from_surface(surface))) {
|
||||
if (layer->current.keyboard_interactive) {
|
||||
seat_set_focus_layer(seat, layer);
|
||||
struct sway_layer_surface *layer = NULL;
|
||||
if ((layer = scene_descriptor_find(scene_node, SWAY_SCENE_DESC_LAYER_SHELL))) {
|
||||
if (layer->layer_surface->current.keyboard_interactive) {
|
||||
seat_set_focus_layer(seat, layer->layer_surface);
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
@ -547,16 +549,14 @@ static void check_focus_follows_mouse(struct sway_seat *seat,
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
node_at_coords(seat, seat->cursor->cursor->x, seat->cursor->cursor->y,
|
||||
&surface, &sx, &sy);
|
||||
struct wlr_scene_node *node = scene_node_at_coords(
|
||||
seat->cursor->cursor->x, seat->cursor->cursor->y, NULL, NULL);
|
||||
|
||||
// Focus topmost layer surface
|
||||
struct wlr_layer_surface_v1 *layer = NULL;
|
||||
if ((layer = toplevel_layer_surface_from_surface(surface)) &&
|
||||
layer->current.keyboard_interactive) {
|
||||
seat_set_focus_layer(seat, layer);
|
||||
struct sway_layer_surface *layer = NULL;
|
||||
if ((layer = scene_descriptor_find(node, SWAY_SCENE_DESC_LAYER_SHELL)) &&
|
||||
layer->layer_surface->current.keyboard_interactive) {
|
||||
seat_set_focus_layer(seat, layer->layer_surface);
|
||||
transaction_commit_dirty();
|
||||
return;
|
||||
}
|
||||
@ -604,8 +604,8 @@ static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) {
|
||||
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_node *node = node_at_coords(seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
struct sway_node *node = node_at_coords(
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (config->focus_follows_mouse != FOLLOWS_NO) {
|
||||
check_focus_follows_mouse(seat, e, node);
|
||||
@ -633,8 +633,8 @@ static void handle_tablet_tool_motion(struct sway_seat *seat,
|
||||
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_node *node = node_at_coords(seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
struct sway_node *node = node_at_coords(
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (config->focus_follows_mouse != FOLLOWS_NO) {
|
||||
check_focus_follows_mouse(seat, e, node);
|
||||
@ -662,7 +662,7 @@ static void handle_touch_down(struct sway_seat *seat,
|
||||
struct wlr_seat *wlr_seat = seat->wlr_seat;
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
double sx, sy;
|
||||
node_at_coords(seat, seat->touch_x, seat->touch_y, &surface, &sx, &sy);
|
||||
node_at_coords(seat->touch_x, seat->touch_y, &surface, &sx, &sy);
|
||||
|
||||
if (surface && wlr_surface_accepts_touch(surface, wlr_seat)) {
|
||||
if (seat_is_input_allowed(seat, surface)) {
|
||||
@ -714,7 +714,7 @@ static void handle_pointer_axis(struct sway_seat *seat,
|
||||
// Determine what's under the cursor
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_node *node = node_at_coords(seat,
|
||||
struct sway_node *node = node_at_coords(
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
struct sway_container *cont = node && node->type == N_CONTAINER ?
|
||||
node->sway_container : NULL;
|
||||
@ -1106,8 +1106,8 @@ static void handle_rebase(struct sway_seat *seat, uint32_t time_msec) {
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx = 0.0, sy = 0.0;
|
||||
e->previous_node = node_at_coords(seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
e->previous_node = node_at_coords(
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (surface) {
|
||||
if (seat_is_input_allowed(seat, surface)) {
|
||||
|
@ -75,7 +75,7 @@ static void handle_touch_down(struct sway_seat *seat,
|
||||
struct seatop_down_event *e = seat->seatop_data;
|
||||
double sx, sy;
|
||||
struct wlr_surface *surface = NULL;
|
||||
struct sway_node *focused_node = node_at_coords(seat, seat->touch_x,
|
||||
struct sway_node *focused_node = node_at_coords(seat->touch_x,
|
||||
seat->touch_y, &surface, &sx, &sy);
|
||||
|
||||
if (!surface || surface != e->surface) { // Must start from the initial surface
|
||||
|
@ -163,8 +163,8 @@ static void handle_motion_postthreshold(struct sway_seat *seat) {
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_cursor *cursor = seat->cursor;
|
||||
struct sway_node *node = node_at_coords(seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
struct sway_node *node = node_at_coords(
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
|
||||
if (!node) {
|
||||
// Eg. hovered over a layer surface such as swaybar
|
||||
|
@ -36,6 +36,31 @@ void *scene_descriptor_try_get(struct wlr_scene_node *node,
|
||||
return desc->data;
|
||||
}
|
||||
|
||||
void *scene_descriptor_find(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type) {
|
||||
while (node) {
|
||||
struct scene_descriptor *desc = scene_node_get_descriptor(node, type);
|
||||
if (desc) {
|
||||
return desc->data;
|
||||
}
|
||||
|
||||
struct sway_popup_desc *popup =
|
||||
scene_descriptor_try_get(node, SWAY_SCENE_DESC_POPUP);
|
||||
if (popup) {
|
||||
node = popup->relative;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!node->parent) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = &node->parent->node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void scene_descriptor_destroy(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type) {
|
||||
struct scene_descriptor *desc = scene_node_get_descriptor(node, type);
|
||||
@ -67,3 +92,14 @@ bool scene_descriptor_assign(struct wlr_scene_node *node,
|
||||
desc->data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool scene_descriptor_reassign(struct wlr_scene_node *node,
|
||||
enum sway_scene_descriptor_type type, void *data) {
|
||||
struct scene_descriptor *desc = scene_node_get_descriptor(node, type);
|
||||
if (desc) {
|
||||
desc->data = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
return scene_descriptor_assign(node, type, data);
|
||||
}
|
||||
|
@ -508,6 +508,8 @@ void container_destroy(struct sway_container *con) {
|
||||
|
||||
if (con->view && con->view->container == con) {
|
||||
con->view->container = NULL;
|
||||
scene_descriptor_destroy(&con->view->scene_tree->node, SWAY_SCENE_DESC_CONTAINER);
|
||||
|
||||
wlr_scene_node_destroy(&con->output_handler->node);
|
||||
if (con->view->destroying) {
|
||||
view_destroy(con->view);
|
||||
|
@ -720,6 +720,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
|
||||
view->surface = wlr_surface;
|
||||
view_populate_pid(view);
|
||||
view->container = container_create(view);
|
||||
scene_descriptor_assign(&view->scene_tree->node,
|
||||
SWAY_SCENE_DESC_CONTAINER, view->container);
|
||||
|
||||
if (view->ctx == NULL) {
|
||||
struct launcher_ctx *ctx = launcher_ctx_find_pid(view->pid);
|
||||
|
Loading…
Reference in New Issue
Block a user