diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 1dd23341..c0c803f1 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -53,16 +53,16 @@ struct sway_container_state { struct sway_container *focused_inactive_child; bool focused; - // View properties - double view_x, view_y; - double view_width, view_height; - enum sway_container_border border; int border_thickness; bool border_top; bool border_bottom; bool border_left; bool border_right; + + // View properties + double view_x, view_y; + double view_width, view_height; }; struct sway_container { @@ -91,6 +91,18 @@ struct sway_container { bool is_fullscreen; + enum sway_container_border border; + + // Used when the view changes to CSD unexpectedly. This will be a non-B_CSD + // border which we use to restore when the view returns to SSD. + enum sway_container_border saved_border; + + int border_thickness; + bool border_top; + bool border_bottom; + bool border_left; + bool border_right; + // The gaps currently applied to the container. double current_gaps; diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 0240f294..67f17914 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -80,24 +80,8 @@ struct sway_view { char *title_format; - // Our border types are B_NONE, B_PIXEL, B_NORMAL and B_CSD. We normally - // just assign this to the border property and ignore the other two. - // However, when a view using CSD is tiled, we want to render our own - // borders as well. So in this case the border property becomes one of the - // first three, and using_csd is true. - // Lastly, views can change their decoration mode at any time. When an SSD - // view becomes CSD without our approval, we save the SSD border type so it - // can be restored if/when the view returns from CSD to SSD. - enum sway_container_border border; - enum sway_container_border saved_border; bool using_csd; - int border_thickness; - bool border_top; - bool border_bottom; - bool border_left; - bool border_right; - struct timespec urgent; bool allow_request_urgent; struct wl_event_source *urgent_timer; diff --git a/sway/commands/border.c b/sway/commands/border.c index 37047812..b6eab550 100644 --- a/sway/commands/border.c +++ b/sway/commands/border.c @@ -12,37 +12,41 @@ // in use (we set using_csd instead and render a sway border). // - view->saved_border should be the last applied border when switching to CSD. // - view->using_csd should always reflect whether CSD is applied or not. -static void set_border(struct sway_view *view, +static void set_border(struct sway_container *con, enum sway_container_border new_border) { - if (view->using_csd && new_border != B_CSD) { - view_set_csd_from_server(view, false); - } else if (!view->using_csd && new_border == B_CSD) { - view_set_csd_from_server(view, true); - view->saved_border = view->border; + if (con->view) { + if (con->view->using_csd && new_border != B_CSD) { + view_set_csd_from_server(con->view, false); + } else if (!con->view->using_csd && new_border == B_CSD) { + view_set_csd_from_server(con->view, true); + con->saved_border = con->border; + } + } + if (new_border != B_CSD || container_is_floating(con)) { + con->border = new_border; } - if (new_border != B_CSD || container_is_floating(view->container)) { - view->border = new_border; + if (con->view) { + con->view->using_csd = new_border == B_CSD; } - view->using_csd = new_border == B_CSD; } -static void border_toggle(struct sway_view *view) { - if (view->using_csd) { - set_border(view, B_NONE); +static void border_toggle(struct sway_container *con) { + if (con->view && con->view->using_csd) { + set_border(con, B_NONE); return; } - switch (view->border) { + switch (con->border) { case B_NONE: - set_border(view, B_PIXEL); + set_border(con, B_PIXEL); break; case B_PIXEL: - set_border(view, B_NORMAL); + set_border(con, B_NORMAL); break; case B_NORMAL: - if (view->xdg_decoration) { - set_border(view, B_CSD); + if (con->view && con->view->xdg_decoration) { + set_border(con, B_CSD); } else { - set_border(view, B_NONE); + set_border(con, B_NONE); } break; case B_CSD: @@ -66,33 +70,33 @@ struct cmd_results *cmd_border(int argc, char **argv) { struct sway_view *view = container->view; if (strcmp(argv[0], "none") == 0) { - set_border(view, B_NONE); + set_border(container, B_NONE); } else if (strcmp(argv[0], "normal") == 0) { - set_border(view, B_NORMAL); + set_border(container, B_NORMAL); } else if (strcmp(argv[0], "pixel") == 0) { - set_border(view, B_PIXEL); + set_border(container, B_PIXEL); } else if (strcmp(argv[0], "csd") == 0) { - if (!view->xdg_decoration) { + if (!view || !view->xdg_decoration) { return cmd_results_new(CMD_INVALID, "border", "This window doesn't support client side decorations"); } - set_border(view, B_CSD); + set_border(container, B_CSD); } else if (strcmp(argv[0], "toggle") == 0) { - border_toggle(view); + border_toggle(container); } else { return cmd_results_new(CMD_INVALID, "border", "Expected 'border ' " "or 'border pixel '"); } if (argc == 2) { - view->border_thickness = atoi(argv[1]); + container->border_thickness = atoi(argv[1]); } - if (container_is_floating(view->container)) { - container_set_geometry_from_floating_view(view->container); + if (container_is_floating(container)) { + container_set_geometry_from_floating_view(container); } - arrange_container(view->container); + arrange_container(container); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index c3efb210..44156d41 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -137,6 +137,12 @@ static void copy_container_state(struct sway_container *container, state->is_fullscreen = container->is_fullscreen; state->parent = container->parent; state->workspace = container->workspace; + state->border = container->border; + state->border_thickness = container->border_thickness; + state->border_top = container->border_top; + state->border_left = container->border_left; + state->border_right = container->border_right; + state->border_bottom = container->border_bottom; if (container->view) { struct sway_view *view = container->view; @@ -144,12 +150,6 @@ static void copy_container_state(struct sway_container *container, state->view_y = view->y; state->view_width = view->width; state->view_height = view->height; - state->border = view->border; - state->border_thickness = view->border_thickness; - state->border_top = view->border_top; - state->border_left = view->border_left; - state->border_right = view->border_right; - state->border_bottom = view->border_bottom; } else { state->children = create_list(); list_cat(state->children, container->children); diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 7ede48bf..c539df40 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -187,23 +187,22 @@ static enum wlr_edges find_edge(struct sway_container *cont, if (!cont->view) { return WLR_EDGE_NONE; } - struct sway_view *view = cont->view; - if (view->border == B_NONE || !view->border_thickness || - view->border == B_CSD) { + if (cont->border == B_NONE || !cont->border_thickness || + cont->border == B_CSD) { return WLR_EDGE_NONE; } enum wlr_edges edge = 0; - if (cursor->cursor->x < cont->x + view->border_thickness) { + if (cursor->cursor->x < cont->x + cont->border_thickness) { edge |= WLR_EDGE_LEFT; } - if (cursor->cursor->y < cont->y + view->border_thickness) { + if (cursor->cursor->y < cont->y + cont->border_thickness) { edge |= WLR_EDGE_TOP; } - if (cursor->cursor->x >= cont->x + cont->width - view->border_thickness) { + if (cursor->cursor->x >= cont->x + cont->width - cont->border_thickness) { edge |= WLR_EDGE_RIGHT; } - if (cursor->cursor->y >= cont->y + cont->height - view->border_thickness) { + if (cursor->cursor->y >= cont->y + cont->height - cont->border_thickness) { edge |= WLR_EDGE_BOTTOM; } diff --git a/sway/tree/container.c b/sway/tree/container.c index 8ab6ebf8..322f2f67 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -639,8 +639,8 @@ void container_init_floating(struct sway_container *con) { view->y = ws->y + (ws->height - view->height) / 2; // If the view's border is B_NONE then these properties are ignored. - view->border_top = view->border_bottom = true; - view->border_left = view->border_right = true; + con->border_top = con->border_bottom = true; + con->border_left = con->border_right = true; container_set_geometry_from_floating_view(con); } @@ -662,7 +662,7 @@ void container_set_floating(struct sway_container *container, bool enable) { if (container->view) { view_set_tiled(container->view, false); if (container->view->using_csd) { - container->view->border = B_CSD; + container->border = B_CSD; } } if (old_parent) { @@ -688,7 +688,7 @@ void container_set_floating(struct sway_container *container, bool enable) { if (container->view) { view_set_tiled(container->view, true); if (container->view->using_csd) { - container->view->border = container->view->saved_border; + container->border = container->saved_border; } } container->is_sticky = false; @@ -710,9 +710,9 @@ void container_set_geometry_from_floating_view(struct sway_container *con) { size_t border_width = 0; size_t top = 0; - if (view->border != B_CSD) { - border_width = view->border_thickness * (view->border != B_NONE); - top = view->border == B_NORMAL ? + if (con->border != B_CSD) { + border_width = con->border_thickness * (con->border != B_NONE); + top = con->border == B_NORMAL ? container_titlebar_height() : border_width; } diff --git a/sway/tree/view.c b/sway/tree/view.c index 4bc9e0f3..9a89b8ea 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -225,21 +225,21 @@ void view_autoconfigure(struct sway_view *view) { bool no_gaps = config->hide_edge_borders != E_SMART_NO_GAPS || !gaps_to_edge(view); - view->border_top = view->border_bottom = true; - view->border_left = view->border_right = true; + con->border_top = con->border_bottom = true; + con->border_left = con->border_right = true; if (config->hide_edge_borders == E_BOTH || config->hide_edge_borders == E_VERTICAL || (smart && !other_views && no_gaps)) { - view->border_left = con->x - con->current_gaps != ws->x; + con->border_left = con->x - con->current_gaps != ws->x; int right_x = con->x + con->width + con->current_gaps; - view->border_right = right_x != ws->x + ws->width; + con->border_right = right_x != ws->x + ws->width; } if (config->hide_edge_borders == E_BOTH || config->hide_edge_borders == E_HORIZONTAL || (smart && !other_views && no_gaps)) { - view->border_top = con->y - con->current_gaps != ws->y; + con->border_top = con->y - con->current_gaps != ws->y; int bottom_y = con->y + con->height + con->current_gaps; - view->border_bottom = bottom_y != ws->y + ws->height; + con->border_bottom = bottom_y != ws->y + ws->height; } double x, y, width, height; @@ -252,14 +252,14 @@ void view_autoconfigure(struct sway_view *view) { enum sway_container_layout layout = container_parent_layout(con); if (layout == L_TABBED && !container_is_floating(con)) { y_offset = container_titlebar_height(); - view->border_top = false; + con->border_top = false; } else if (layout == L_STACKED && !container_is_floating(con)) { list_t *siblings = container_get_siblings(con); y_offset = container_titlebar_height() * siblings->length; - view->border_top = false; + con->border_top = false; } - switch (view->border) { + switch (con->border) { case B_CSD: case B_NONE: x = con->x; @@ -268,29 +268,29 @@ void view_autoconfigure(struct sway_view *view) { height = con->height - y_offset; break; case B_PIXEL: - x = con->x + view->border_thickness * view->border_left; - y = con->y + view->border_thickness * view->border_top + y_offset; + x = con->x + con->border_thickness * con->border_left; + y = con->y + con->border_thickness * con->border_top + y_offset; width = con->width - - view->border_thickness * view->border_left - - view->border_thickness * view->border_right; + - con->border_thickness * con->border_left + - con->border_thickness * con->border_right; height = con->height - y_offset - - view->border_thickness * view->border_top - - view->border_thickness * view->border_bottom; + - con->border_thickness * con->border_top + - con->border_thickness * con->border_bottom; break; case B_NORMAL: // Height is: 1px border + 3px pad + title height + 3px pad + 1px border - x = con->x + view->border_thickness * view->border_left; + x = con->x + con->border_thickness * con->border_left; width = con->width - - view->border_thickness * view->border_left - - view->border_thickness * view->border_right; + - con->border_thickness * con->border_left + - con->border_thickness * con->border_right; if (y_offset) { y = con->y + y_offset; height = con->height - y_offset - - view->border_thickness * view->border_bottom; + - con->border_thickness * con->border_bottom; } else { y = con->y + container_titlebar_height(); height = con->height - container_titlebar_height() - - view->border_thickness * view->border_bottom; + - con->border_thickness * con->border_bottom; } break; } @@ -347,13 +347,14 @@ void view_set_csd_from_server(struct sway_view *view, bool enabled) { void view_update_csd_from_client(struct sway_view *view, bool enabled) { wlr_log(WLR_DEBUG, "View %p updated CSD to %i", view, enabled); - if (enabled && view->border != B_CSD) { - view->saved_border = view->border; - if (view->container && container_is_floating(view->container)) { - view->border = B_CSD; + struct sway_container *con = view->container; + if (enabled && con && con->border != B_CSD) { + con->saved_border = con->border; + if (container_is_floating(con)) { + con->border = B_CSD; } - } else if (!enabled && view->border == B_CSD) { - view->border = view->saved_border; + } else if (!enabled && con && con->border == B_CSD) { + con->border = con->saved_border; } view->using_csd = enabled; } @@ -584,12 +585,12 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, view->surface_new_subsurface.notify = view_handle_surface_new_subsurface; if (view->impl->wants_floating && view->impl->wants_floating(view)) { - view->border = config->floating_border; - view->border_thickness = config->floating_border_thickness; + view->container->border = config->floating_border; + view->container->border_thickness = config->floating_border_thickness; container_set_floating(view->container, true); } else { - view->border = config->border; - view->border_thickness = config->border_thickness; + view->container->border = config->border; + view->container->border_thickness = config->border_thickness; view_set_tiled(view, true); }