ssd: Allocate struct ssd and struct ssd_hover_state separately

- Store a pointer to the `struct view` in `struct ssd`
- Pass `struct ssd *` instead of `struct view *` to ssd functions
- Add `ssd_get_margin()` convenience function
This commit is contained in:
John Lindgren 2022-11-26 16:46:28 -05:00 committed by Johan Malm
parent cfa51ab628
commit 1e8b0414fe
15 changed files with 112 additions and 65 deletions

View file

@ -50,7 +50,6 @@
#include "cursor.h" #include "cursor.h"
#include "config/keybind.h" #include "config/keybind.h"
#include "config/rcxml.h" #include "config/rcxml.h"
#include "ssd.h"
#if HAVE_NLS #if HAVE_NLS
#include <libintl.h> #include <libintl.h>
#include <locale.h> #include <locale.h>
@ -232,7 +231,7 @@ struct server {
/* SSD state */ /* SSD state */
struct view *focused_view; struct view *focused_view;
struct ssd_hover_state ssd_hover_state; struct ssd_hover_state *ssd_hover_state;
/* Tree for all non-layer xdg/xwayland-shell surfaces */ /* Tree for all non-layer xdg/xwayland-shell surfaces */
struct wlr_scene_tree *view_tree; struct wlr_scene_tree *view_tree;

View file

@ -80,6 +80,7 @@ struct ssd_state_title_width {
}; };
struct ssd { struct ssd {
struct view *view;
struct wlr_scene_tree *tree; struct wlr_scene_tree *tree;
/* /*
@ -144,12 +145,23 @@ struct ssd_hover_state {
struct wlr_scene_node *node; struct wlr_scene_node *node;
}; };
/* Public SSD API */ /*
void ssd_create(struct view *view, bool active); * Public SSD API
void ssd_set_active(struct view *view, bool active); *
void ssd_update_title(struct view *view); * For convenience in dealing with non-SSD views, this API allows NULL
void ssd_update_geometry(struct view *view); * ssd/button/node arguments and attempts to do something sensible in
void ssd_destroy(struct view *view); * that case (e.g. no-op/return default values).
*
* NULL scene/view arguments are not allowed.
*/
struct ssd *ssd_create(struct view *view, bool active);
struct border ssd_get_margin(const struct ssd *ssd);
void ssd_set_active(struct ssd *ssd, bool active);
void ssd_update_title(struct ssd *ssd);
void ssd_update_geometry(struct ssd *ssd);
void ssd_destroy(struct ssd *ssd);
struct ssd_hover_state *ssd_hover_state_new(void);
void ssd_update_button_hover(struct wlr_scene_node *node, void ssd_update_button_hover(struct wlr_scene_node *node,
struct ssd_hover_state *hover_state); struct ssd_hover_state *hover_state);

View file

@ -7,7 +7,6 @@
#include <stdint.h> #include <stdint.h>
#include <wayland-util.h> #include <wayland-util.h>
#include <wlr/util/box.h> #include <wlr/util/box.h>
#include "ssd.h"
/* /*
* In labwc, a view is a container for surfaces which can be moved around by * In labwc, a view is a container for surfaces which can be moved around by
@ -21,6 +20,7 @@ enum view_type {
#endif #endif
}; };
struct view;
struct view_impl { struct view_impl {
void (*configure)(struct view *view, struct wlr_box geo); void (*configure)(struct view *view, struct wlr_box geo);
void (*close)(struct view *view); void (*close)(struct view *view);
@ -65,7 +65,7 @@ struct view {
uint32_t configure_serial; uint32_t configure_serial;
} pending_move_resize; } pending_move_resize;
struct ssd ssd; struct ssd *ssd;
struct wlr_foreign_toplevel_handle_v1 *toplevel_handle; struct wlr_foreign_toplevel_handle_v1 *toplevel_handle;
struct wl_listener toplevel_handle_request_maximize; struct wl_listener toplevel_handle_request_maximize;

View file

@ -161,7 +161,7 @@ show_menu(struct server *server, struct view *view, const char *menu_name)
if (!view) { if (!view) {
return; return;
} }
enum ssd_part_type type = ssd_at(&view->ssd, server->scene, enum ssd_part_type type = ssd_at(view->ssd, server->scene,
server->seat.cursor->x, server->seat.cursor->y); server->seat.cursor->x, server->seat.cursor->y);
if (type == LAB_SSD_BUTTON_WINDOW_MENU) { if (type == LAB_SSD_BUTTON_WINDOW_MENU) {
force_menu_top_left = true; force_menu_top_left = true;

View file

@ -330,7 +330,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx,
struct seat *seat = &server->seat; struct seat *seat = &server->seat;
struct wlr_seat *wlr_seat = seat->seat; struct wlr_seat *wlr_seat = seat->seat;
ssd_update_button_hover(ctx->node, &server->ssd_hover_state); ssd_update_button_hover(ctx->node, server->ssd_hover_state);
if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) { if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
/* /*

View file

@ -61,7 +61,7 @@ get_view_part(struct view *view, struct wlr_scene_node *node)
return "view->scene_node"; return "view->scene_node";
} }
if (view) { if (view) {
return ssd_debug_get_node_name(&view->ssd, node); return ssd_debug_get_node_name(view->ssd, node);
} }
return NULL; return NULL;
} }
@ -159,7 +159,7 @@ dump_tree(struct server *server, struct wlr_scene_node *node,
if ((IGNORE_MENU && node == &server->menu_tree->node) if ((IGNORE_MENU && node == &server->menu_tree->node)
|| (IGNORE_SSD && view || (IGNORE_SSD && view
&& ssd_debug_is_root_node(&view->ssd, node))) { && ssd_debug_is_root_node(view->ssd, node))) {
printf("%*c%s\n", pos + 4 + INDENT_SIZE, ' ', "<skipping children>"); printf("%*c%s\n", pos + 4 + INDENT_SIZE, ' ', "<skipping children>");
return; return;
} }

View file

@ -339,7 +339,7 @@ get_cursor_context(struct server *server)
case LAB_NODE_DESC_VIEW: case LAB_NODE_DESC_VIEW:
case LAB_NODE_DESC_XDG_POPUP: case LAB_NODE_DESC_XDG_POPUP:
ret.view = desc->data; ret.view = desc->data;
ret.type = ssd_get_part_type(&ret.view->ssd, ret.node); ret.type = ssd_get_part_type(ret.view->ssd, ret.node);
if (ret.type == LAB_SSD_CLIENT) { if (ret.type == LAB_SSD_CLIENT) {
ret.surface = lab_wlr_surface_from_node(ret.node); ret.surface = lab_wlr_surface_from_node(ret.node);
} }

View file

@ -41,7 +41,7 @@ resistance_move_apply(struct view *view, double *x, double *y)
struct wlr_box tgeom = {.x = *x, .y = *y, .width = view->w, struct wlr_box tgeom = {.x = *x, .y = *y, .width = view->w,
.height = view->h}; .height = view->h};
struct output *output; struct output *output;
struct border border = view->ssd.margin; struct border border = ssd_get_margin(view->ssd);
struct edges view_edges; /* The edges of the current view */ struct edges view_edges; /* The edges of the current view */
struct edges target_edges; /* The desired edges */ struct edges target_edges; /* The desired edges */
struct edges other_edges; /* The edges of the monitor/other view */ struct edges other_edges; /* The edges of the monitor/other view */
@ -112,7 +112,7 @@ resistance_resize_apply(struct view *view, struct wlr_box *new_view_geo)
.height = view->h}; .height = view->h};
struct wlr_box tgeom = {.x = new_view_geo->x, .y = new_view_geo->y, struct wlr_box tgeom = {.x = new_view_geo->x, .y = new_view_geo->y,
.width = new_view_geo->width, .height = new_view_geo->height}; .width = new_view_geo->width, .height = new_view_geo->height};
struct border border = view->ssd.margin; struct border border = ssd_get_margin(view->ssd);
struct edges view_edges; /* The edges of the current view */ struct edges view_edges; /* The edges of the current view */
struct edges target_edges; /* The desired edges */ struct edges target_edges; /* The desired edges */
struct edges other_edges; /* The edges of the monitor/other view */ struct edges other_edges; /* The edges of the monitor/other view */

View file

@ -221,6 +221,8 @@ server_init(struct server *server)
wl_list_init(&server->views); wl_list_init(&server->views);
wl_list_init(&server->unmanaged_surfaces); wl_list_init(&server->unmanaged_surfaces);
server->ssd_hover_state = ssd_hover_state_new();
server->scene = wlr_scene_create(); server->scene = wlr_scene_create();
if (!server->scene) { if (!server->scene) {
wlr_log(WLR_ERROR, "unable to create scene"); wlr_log(WLR_ERROR, "unable to create scene");

View file

@ -7,6 +7,7 @@
*/ */
#include <assert.h> #include <assert.h>
#include "common/mem.h"
#include "common/scene-helpers.h" #include "common/scene-helpers.h"
#include "labwc.h" #include "labwc.h"
#include "ssd.h" #include "ssd.h"
@ -16,6 +17,7 @@
struct border struct border
ssd_thickness(struct view *view) ssd_thickness(struct view *view)
{ {
assert(view);
/* /*
* Check preconditions for displaying SSD. Note that this * Check preconditions for displaying SSD. Note that this
* needs to work even before ssd_create() has been called. * needs to work even before ssd_create() has been called.
@ -35,6 +37,7 @@ ssd_thickness(struct view *view)
struct wlr_box struct wlr_box
ssd_max_extents(struct view *view) ssd_max_extents(struct view *view)
{ {
assert(view);
struct border border = ssd_thickness(view); struct border border = ssd_thickness(view);
return (struct wlr_box){ return (struct wlr_box){
.x = view->x - border.left, .x = view->x - border.left,
@ -61,7 +64,7 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
} else if (node->type == WLR_SCENE_NODE_BUFFER } else if (node->type == WLR_SCENE_NODE_BUFFER
&& lab_wlr_surface_from_node(node)) { && lab_wlr_surface_from_node(node)) {
return LAB_SSD_CLIENT; return LAB_SSD_CLIENT;
} else if (!ssd->tree) { } else if (!ssd) {
return LAB_SSD_NONE; return LAB_SSD_NONE;
} }
@ -114,6 +117,7 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
enum ssd_part_type enum ssd_part_type
ssd_at(const struct ssd *ssd, struct wlr_scene *scene, double lx, double ly) ssd_at(const struct ssd *ssd, struct wlr_scene *scene, double lx, double ly)
{ {
assert(scene);
double sx, sy; double sx, sy;
struct wlr_scene_node *node = wlr_scene_node_at( struct wlr_scene_node *node = wlr_scene_node_at(
&scene->tree.node, lx, ly, &sx, &sy); &scene->tree.node, lx, ly, &sx, &sy);
@ -145,34 +149,43 @@ ssd_resize_edges(enum ssd_part_type type)
} }
} }
void struct ssd *
ssd_create(struct view *view, bool active) ssd_create(struct view *view, bool active)
{ {
struct ssd *ssd = &view->ssd; assert(view);
assert(!ssd->tree); struct ssd *ssd = znew(*ssd);
ssd->view = view;
ssd->tree = wlr_scene_tree_create(view->scene_tree); ssd->tree = wlr_scene_tree_create(view->scene_tree);
wlr_scene_node_lower_to_bottom(&ssd->tree->node); wlr_scene_node_lower_to_bottom(&ssd->tree->node);
ssd_extents_create(ssd); ssd_extents_create(ssd);
ssd_border_create(ssd); ssd_border_create(ssd);
ssd_titlebar_create(ssd); ssd_titlebar_create(ssd);
ssd->margin = ssd_thickness(view); ssd->margin = ssd_thickness(view);
ssd_set_active(view, active); ssd_set_active(ssd, active);
ssd->state.width = view->w; ssd->state.width = view->w;
ssd->state.height = view->h; ssd->state.height = view->h;
ssd->state.x = view->x; ssd->state.x = view->x;
ssd->state.y = view->y; ssd->state.y = view->y;
return ssd;
}
struct border
ssd_get_margin(const struct ssd *ssd)
{
return ssd ? ssd->margin : (struct border){ 0 };
} }
void void
ssd_update_geometry(struct view *view) ssd_update_geometry(struct ssd *ssd)
{ {
struct ssd *ssd = &view->ssd; if (!ssd) {
if (!ssd->tree) {
return; return;
} }
struct view *view = ssd->view;
if (view->w == ssd->state.width && view->h == ssd->state.height) { if (view->w == ssd->state.width && view->h == ssd->state.height) {
if (view->x != ssd->state.x || view->y != ssd->state.y) { if (view->x != ssd->state.x || view->y != ssd->state.y) {
/* Dynamically resize extents based on position and usable_area */ /* Dynamically resize extents based on position and usable_area */
@ -193,16 +206,16 @@ ssd_update_geometry(struct view *view)
} }
void void
ssd_destroy(struct view *view) ssd_destroy(struct ssd *ssd)
{ {
struct ssd *ssd = &view->ssd; if (!ssd) {
if (!ssd->tree) {
return; return;
} }
/* Maybe reset hover view */ /* Maybe reset hover view */
struct view *view = ssd->view;
struct ssd_hover_state *hover_state; struct ssd_hover_state *hover_state;
hover_state = &view->server->ssd_hover_state; hover_state = view->server->ssd_hover_state;
if (hover_state->view == view) { if (hover_state->view == view) {
hover_state->view = NULL; hover_state->view = NULL;
hover_state->node = NULL; hover_state->node = NULL;
@ -213,8 +226,8 @@ ssd_destroy(struct view *view)
ssd_border_destroy(ssd); ssd_border_destroy(ssd);
ssd_extents_destroy(ssd); ssd_extents_destroy(ssd);
wlr_scene_node_destroy(&ssd->tree->node); wlr_scene_node_destroy(&ssd->tree->node);
ssd->tree = NULL;
ssd->margin = (struct border){ 0 }; free(ssd);
} }
bool bool
@ -256,10 +269,9 @@ ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate)
} }
void void
ssd_set_active(struct view *view, bool active) ssd_set_active(struct ssd *ssd, bool active)
{ {
struct ssd *ssd = &view->ssd; if (!ssd) {
if (!ssd->tree) {
return; return;
} }
wlr_scene_node_set_enabled(&ssd->border.active.tree->node, active); wlr_scene_node_set_enabled(&ssd->border.active.tree->node, active);
@ -268,10 +280,16 @@ ssd_set_active(struct view *view, bool active)
wlr_scene_node_set_enabled(&ssd->titlebar.inactive.tree->node, !active); wlr_scene_node_set_enabled(&ssd->titlebar.inactive.tree->node, !active);
} }
struct ssd_hover_state *
ssd_hover_state_new(void)
{
return znew(struct ssd_hover_state);
}
bool bool
ssd_debug_is_root_node(const struct ssd *ssd, struct wlr_scene_node *node) ssd_debug_is_root_node(const struct ssd *ssd, struct wlr_scene_node *node)
{ {
if (!ssd->tree || !node) { if (!ssd || !node) {
return false; return false;
} }
return node == &ssd->tree->node; return node == &ssd->tree->node;
@ -280,7 +298,7 @@ ssd_debug_is_root_node(const struct ssd *ssd, struct wlr_scene_node *node)
const char * const char *
ssd_debug_get_node_name(const struct ssd *ssd, struct wlr_scene_node *node) ssd_debug_get_node_name(const struct ssd *ssd, struct wlr_scene_node *node)
{ {
if (!ssd->tree || !node) { if (!ssd || !node) {
return NULL; return NULL;
} }
if (node == &ssd->tree->node) { if (node == &ssd->tree->node) {

View file

@ -13,7 +13,7 @@
void void
ssd_border_create(struct ssd *ssd) ssd_border_create(struct ssd *ssd)
{ {
struct view *view = wl_container_of(ssd, view, ssd); struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->w;
int height = view->h; int height = view->h;
@ -51,7 +51,7 @@ ssd_border_create(struct ssd *ssd)
void void
ssd_border_update(struct ssd *ssd) ssd_border_update(struct ssd *ssd)
{ {
struct view *view = wl_container_of(ssd, view, ssd); struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->w;

View file

@ -37,7 +37,7 @@ lab_wlr_output_layout_layout_coords(struct wlr_output_layout *layout,
void void
ssd_extents_create(struct ssd *ssd) ssd_extents_create(struct ssd *ssd)
{ {
struct view *view = wl_container_of(ssd, view, ssd); struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
struct wl_list *part_list = &ssd->extents.parts; struct wl_list *part_list = &ssd->extents.parts;
int extended_area = EXTENDED_AREA; int extended_area = EXTENDED_AREA;
@ -98,7 +98,7 @@ ssd_extents_create(struct ssd *ssd)
void void
ssd_extents_update(struct ssd *ssd) ssd_extents_update(struct ssd *ssd)
{ {
struct view *view = wl_container_of(ssd, view, ssd); struct view *view = ssd->view;
if (view->maximized || view->fullscreen) { if (view->maximized || view->fullscreen) {
wlr_scene_node_set_enabled(&ssd->extents.tree->node, false); wlr_scene_node_set_enabled(&ssd->extents.tree->node, false);
return; return;

View file

@ -20,7 +20,7 @@
void void
ssd_titlebar_create(struct ssd *ssd) ssd_titlebar_create(struct ssd *ssd)
{ {
struct view *view = wl_container_of(ssd, view, ssd); struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->w;
@ -78,7 +78,7 @@ ssd_titlebar_create(struct ssd *ssd)
corner_top_right, close_button_unpressed, corner_top_right, close_button_unpressed,
width - BUTTON_WIDTH * 1, view); width - BUTTON_WIDTH * 1, view);
} FOR_EACH_END } FOR_EACH_END
ssd_update_title(view); ssd_update_title(ssd);
} }
static bool static bool
@ -90,7 +90,7 @@ is_direct_child(struct wlr_scene_node *node, struct ssd_sub_tree *subtree)
void void
ssd_titlebar_update(struct ssd *ssd) ssd_titlebar_update(struct ssd *ssd)
{ {
struct view *view = wl_container_of(ssd, view, ssd); struct view *view = ssd->view;
int width = view->w; int width = view->w;
if (width == ssd->state.width) { if (width == ssd->state.width) {
return; return;
@ -131,7 +131,7 @@ ssd_titlebar_update(struct ssd *ssd)
} }
} }
} FOR_EACH_END } FOR_EACH_END
ssd_update_title(view); ssd_update_title(ssd);
} }
void void
@ -169,7 +169,7 @@ ssd_titlebar_destroy(struct ssd *ssd)
static void static void
ssd_update_title_positions(struct ssd *ssd) ssd_update_title_positions(struct ssd *ssd)
{ {
struct view *view = wl_container_of(ssd, view, ssd); struct view *view = ssd->view;
struct theme *theme = view->server->theme; struct theme *theme = view->server->theme;
int width = view->w; int width = view->w;
int title_bg_width = width - BUTTON_WIDTH * BUTTON_COUNT; int title_bg_width = width - BUTTON_WIDTH * BUTTON_COUNT;
@ -219,13 +219,13 @@ ssd_update_title_positions(struct ssd *ssd)
} }
void void
ssd_update_title(struct view *view) ssd_update_title(struct ssd *ssd)
{ {
struct ssd *ssd = &view->ssd; if (!ssd) {
if (!ssd->tree) {
return; return;
} }
struct view *view = ssd->view;
char *title = (char *)view_get_string_prop(view, "title"); char *title = (char *)view_get_string_prop(view, "title");
if (!title || !*title) { if (!title || !*title) {
return; return;

View file

@ -88,7 +88,7 @@ view_get_edge_snap_box(struct view *view, struct output *output,
break; break;
} }
struct border margin = view->ssd.margin; struct border margin = ssd_get_margin(view->ssd);
struct wlr_box dst = { struct wlr_box dst = {
.x = x_offset + usable.x + margin.left, .x = x_offset + usable.x + margin.left,
.y = y_offset + usable.y + margin.top, .y = y_offset + usable.y + margin.top,
@ -102,9 +102,7 @@ view_get_edge_snap_box(struct view *view, struct output *output,
static void static void
_view_set_activated(struct view *view, bool activated) _view_set_activated(struct view *view, bool activated)
{ {
if (view->ssd.tree) { ssd_set_active(view->ssd, activated);
ssd_set_active(view, activated);
}
if (view->impl->set_activated) { if (view->impl->set_activated) {
view->impl->set_activated(view, activated); view->impl->set_activated(view, activated);
} }
@ -153,7 +151,7 @@ view_moved(struct view *view)
assert(view); assert(view);
wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y); wlr_scene_node_set_position(&view->scene_tree->node, view->x, view->y);
view_discover_output(view); view_discover_output(view);
ssd_update_geometry(view); ssd_update_geometry(view->ssd);
cursor_update_focus(view->server); cursor_update_focus(view->server);
} }
@ -278,7 +276,7 @@ view_compute_centered_position(struct view *view, int w, int h, int *x, int *y)
return false; return false;
} }
struct border margin = view->ssd.margin; struct border margin = ssd_get_margin(view->ssd);
struct wlr_box usable = output_usable_area_in_layout_coords(output); struct wlr_box usable = output_usable_area_in_layout_coords(output);
int width = w + margin.left + margin.right; int width = w + margin.left + margin.right;
int height = h + margin.top + margin.bottom; int height = h + margin.top + margin.bottom;
@ -554,6 +552,22 @@ view_move_to_workspace(struct view *view, struct workspace *workspace)
} }
} }
static void
decorate(struct view *view)
{
if (!view->ssd) {
view->ssd = ssd_create(view,
view == view->server->focused_view);
}
}
static void
undecorate(struct view *view)
{
ssd_destroy(view->ssd);
view->ssd = NULL;
}
void void
view_set_decorations(struct view *view, bool decorations) view_set_decorations(struct view *view, bool decorations)
{ {
@ -565,9 +579,9 @@ view_set_decorations(struct view *view, bool decorations)
*/ */
view->ssd_enabled = decorations; view->ssd_enabled = decorations;
if (decorations) { if (decorations) {
ssd_create(view, view == view->server->focused_view); decorate(view);
} else { } else {
ssd_destroy(view); undecorate(view);
} }
if (view->maximized) { if (view->maximized) {
view_apply_maximized_geometry(view); view_apply_maximized_geometry(view);
@ -614,7 +628,7 @@ view_set_fullscreen(struct view *view, bool fullscreen,
} }
/* Hide decorations when going fullscreen */ /* Hide decorations when going fullscreen */
if (view->ssd_enabled) { if (view->ssd_enabled) {
ssd_destroy(view); undecorate(view);
} }
view->fullscreen = wlr_output; view->fullscreen = wlr_output;
view_apply_fullscreen_geometry(view, view->fullscreen); view_apply_fullscreen_geometry(view, view->fullscreen);
@ -630,7 +644,7 @@ view_set_fullscreen(struct view *view, bool fullscreen,
} }
/* Re-show decorations when no longer fullscreen */ /* Re-show decorations when no longer fullscreen */
if (view->ssd_enabled) { if (view->ssd_enabled) {
ssd_create(view, view == view->server->focused_view); decorate(view);
} }
} }
@ -734,7 +748,7 @@ view_move_to_edge(struct view *view, const char *direction)
return; return;
} }
struct border margin = view->ssd.margin; struct border margin = ssd_get_margin(view->ssd);
struct wlr_box usable = output_usable_area_in_layout_coords(output); struct wlr_box usable = output_usable_area_in_layout_coords(output);
if (usable.height == output->wlr_output->height if (usable.height == output->wlr_output->height
&& output->wlr_output->scale != 1) { && output->wlr_output->scale != 1) {
@ -872,7 +886,7 @@ view_update_title(struct view *view)
if (!view->toplevel_handle || !title) { if (!view->toplevel_handle || !title) {
return; return;
} }
ssd_update_title(view); ssd_update_title(view->ssd);
wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, title); wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, title);
} }
@ -893,8 +907,8 @@ view_reload_ssd(struct view *view)
{ {
assert(view); assert(view);
if (view->ssd_enabled && !view->fullscreen) { if (view->ssd_enabled && !view->fullscreen) {
ssd_destroy(view); undecorate(view);
ssd_create(view, view == view->server->focused_view); decorate(view);
} }
} }
@ -926,9 +940,9 @@ view_destroy(struct view *view)
} }
osd_on_view_destroy(view); osd_on_view_destroy(view);
undecorate(view);
if (view->scene_tree) { if (view->scene_tree) {
ssd_destroy(view);
wlr_scene_node_destroy(&view->scene_tree->node); wlr_scene_node_destroy(&view->scene_tree->node);
view->scene_tree = NULL; view->scene_tree = NULL;
} }

View file

@ -303,8 +303,10 @@ position_xdg_toplevel_view(struct view *view)
view->x = center_x - xdg_surface->current.geometry.width / 2; view->x = center_x - xdg_surface->current.geometry.width / 2;
view->y = center_y - xdg_surface->current.geometry.height / 2; view->y = center_y - xdg_surface->current.geometry.height / 2;
} }
view->x += view->ssd.margin.left;
view->y += view->ssd.margin.top; struct border margin = ssd_get_margin(view->ssd);
view->x += margin.left;
view->y += margin.top;
} }
static const char * static const char *