diff --git a/include/sway/decoration.h b/include/sway/decoration.h index 7916746e6..6f9a160ba 100644 --- a/include/sway/decoration.h +++ b/include/sway/decoration.h @@ -5,6 +5,7 @@ struct sway_server_decoration { struct wlr_server_decoration *wlr_server_decoration; + struct sway_view *view; struct wl_list link; struct wl_listener destroy; diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 5e281a2f8..6019602c9 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -28,6 +28,7 @@ enum sway_container_border { B_NONE, B_PIXEL, B_NORMAL, + B_CSD, }; struct sway_root; @@ -63,7 +64,6 @@ struct sway_container_state { bool border_bottom; bool border_left; bool border_right; - bool using_csd; }; struct sway_container { diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index d10251dda..5b95289ed 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -60,6 +60,7 @@ struct sway_view { struct sway_container *container; // NULL if unmapped and transactions finished struct wlr_surface *surface; // NULL for unmapped views + struct sway_server_decoration *decoration; pid_t pid; @@ -81,7 +82,6 @@ struct sway_view { bool border_bottom; bool border_left; bool border_right; - bool using_csd; struct timespec urgent; bool allow_request_urgent; @@ -268,6 +268,8 @@ void view_set_activated(struct sway_view *view, bool activated); */ void view_request_activate(struct sway_view *view); +void view_set_csd(struct sway_view *view, bool enabled); + void view_set_tiled(struct sway_view *view, bool tiled); void view_close(struct sway_view *view); diff --git a/sway/commands/border.c b/sway/commands/border.c index 95498b2f8..f69d3740b 100644 --- a/sway/commands/border.c +++ b/sway/commands/border.c @@ -7,6 +7,16 @@ #include "sway/tree/container.h" #include "sway/tree/view.h" +static void set_border(struct sway_view *view, + enum sway_container_border new_border) { + if (view->border == B_CSD && new_border != B_CSD) { + view_set_csd(view, false); + } else if (view->border != B_CSD && new_border == B_CSD) { + view_set_csd(view, true); + } + view->border = new_border; +} + struct cmd_results *cmd_border(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "border", EXPECTED_AT_LEAST, 1))) { @@ -21,13 +31,15 @@ struct cmd_results *cmd_border(int argc, char **argv) { struct sway_view *view = container->view; if (strcmp(argv[0], "none") == 0) { - view->border = B_NONE; + set_border(view, B_NONE); } else if (strcmp(argv[0], "normal") == 0) { - view->border = B_NORMAL; + set_border(view, B_NORMAL); } else if (strcmp(argv[0], "pixel") == 0) { - view->border = B_PIXEL; + set_border(view, B_PIXEL); + } else if (strcmp(argv[0], "csd") == 0) { + set_border(view, B_CSD); } else if (strcmp(argv[0], "toggle") == 0) { - view->border = (view->border + 1) % 3; + set_border(view, (view->border + 1) % 4); } else { return cmd_results_new(CMD_INVALID, "border", "Expected 'border ' " diff --git a/sway/decoration.c b/sway/decoration.c index 0e3e67ac8..8d3b03e7b 100644 --- a/sway/decoration.c +++ b/sway/decoration.c @@ -8,6 +8,7 @@ static void server_decoration_handle_destroy(struct wl_listener *listener, void *data) { struct sway_server_decoration *deco = wl_container_of(listener, deco, destroy); + deco->view->decoration = NULL; wl_list_remove(&deco->destroy.link); wl_list_remove(&deco->mode.link); wl_list_remove(&deco->link); @@ -49,6 +50,8 @@ void handle_server_decoration(struct wl_listener *listener, void *data) { } deco->wlr_server_decoration = wlr_deco; + deco->view = view_from_wlr_surface(wlr_deco->surface); + deco->view->decoration = deco; wl_signal_add(&wlr_deco->events.destroy, &deco->destroy); deco->destroy.notify = server_decoration_handle_destroy; diff --git a/sway/desktop/render.c b/sway/desktop/render.c index af4e29057..c8b08a585 100644 --- a/sway/desktop/render.c +++ b/sway/desktop/render.c @@ -272,7 +272,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, render_view_toplevels(view, output, damage, view->container->alpha); } - if (view->container->current.using_csd) { + if (con->current.border == B_NONE || con->current.border == B_CSD) { return; } @@ -281,51 +281,49 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage, float color[4]; struct sway_container_state *state = &con->current; - if (state->border != B_NONE) { - if (state->border_left) { + if (state->border_left) { + memcpy(&color, colors->child_border, sizeof(float) * 4); + premultiply_alpha(color, con->alpha); + box.x = state->con_x; + box.y = state->view_y; + box.width = state->border_thickness; + box.height = state->view_height; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + } + + list_t *siblings = container_get_current_siblings(con); + enum sway_container_layout layout = + container_current_parent_layout(con); + + if (state->border_right) { + if (siblings->length == 1 && layout == L_HORIZ) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { memcpy(&color, colors->child_border, sizeof(float) * 4); - premultiply_alpha(color, con->alpha); - box.x = state->con_x; - box.y = state->view_y; - box.width = state->border_thickness; - box.height = state->view_height; - scale_box(&box, output_scale); - render_rect(output->wlr_output, damage, &box, color); } + premultiply_alpha(color, con->alpha); + box.x = state->view_x + state->view_width; + box.y = state->view_y; + box.width = state->border_thickness; + box.height = state->view_height; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); + } - list_t *siblings = container_get_current_siblings(con); - enum sway_container_layout layout = - container_current_parent_layout(con); - - if (state->border_right) { - if (siblings->length == 1 && layout == L_HORIZ) { - memcpy(&color, colors->indicator, sizeof(float) * 4); - } else { - memcpy(&color, colors->child_border, sizeof(float) * 4); - } - premultiply_alpha(color, con->alpha); - box.x = state->view_x + state->view_width; - box.y = state->view_y; - box.width = state->border_thickness; - box.height = state->view_height; - scale_box(&box, output_scale); - render_rect(output->wlr_output, damage, &box, color); - } - - if (state->border_bottom) { - if (siblings->length == 1 && layout == L_VERT) { - memcpy(&color, colors->indicator, sizeof(float) * 4); - } else { - memcpy(&color, colors->child_border, sizeof(float) * 4); - } - premultiply_alpha(color, con->alpha); - box.x = state->con_x; - box.y = state->view_y + state->view_height; - box.width = state->con_width; - box.height = state->border_thickness; - scale_box(&box, output_scale); - render_rect(output->wlr_output, damage, &box, color); + if (state->border_bottom) { + if (siblings->length == 1 && layout == L_VERT) { + memcpy(&color, colors->indicator, sizeof(float) * 4); + } else { + memcpy(&color, colors->child_border, sizeof(float) * 4); } + premultiply_alpha(color, con->alpha); + box.x = state->con_x; + box.y = state->view_y + state->view_height; + box.width = state->con_width; + box.height = state->border_thickness; + scale_box(&box, output_scale); + render_rect(output->wlr_output, damage, &box, color); } } @@ -645,14 +643,12 @@ static void render_containers_linear(struct sway_output *output, marks_texture = view->marks_unfocused; } - if (!view->container->current.using_csd) { - if (state->border == B_NORMAL) { - render_titlebar(output, damage, child, state->con_x, - state->con_y, state->con_width, colors, - title_texture, marks_texture); - } else { - render_top_border(output, damage, child, colors); - } + if (state->border == B_NORMAL) { + render_titlebar(output, damage, child, state->con_x, + state->con_y, state->con_width, colors, + title_texture, marks_texture); + } else if (state->border == B_PIXEL) { + render_top_border(output, damage, child, colors); } render_view(output, damage, child, colors); } else { @@ -859,14 +855,12 @@ static void render_floating_container(struct sway_output *soutput, marks_texture = view->marks_unfocused; } - if (!view->container->current.using_csd) { - if (con->current.border == B_NORMAL) { - render_titlebar(soutput, damage, con, con->current.con_x, - con->current.con_y, con->current.con_width, colors, - title_texture, marks_texture); - } else if (con->current.border != B_NONE) { - render_top_border(soutput, damage, con, colors); - } + if (con->current.border == B_NORMAL) { + render_titlebar(soutput, damage, con, con->current.con_x, + con->current.con_y, con->current.con_width, colors, + title_texture, marks_texture); + } else if (con->current.border == B_PIXEL) { + render_top_border(soutput, damage, con, colors); } render_view(soutput, damage, con, colors); } else { diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 797f6b4cb..4624d8245 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -167,7 +167,6 @@ static void copy_container_state(struct sway_container *container, state->border_left = view->border_left; state->border_right = view->border_right; state->border_bottom = view->border_bottom; - state->using_csd = view->using_csd; } else { state->children = create_list(); list_cat(state->children, container->children); diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 5111e8e5c..18217b867 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -175,7 +175,8 @@ static enum wlr_edges find_edge(struct sway_container *cont, return WLR_EDGE_NONE; } struct sway_view *view = cont->view; - if (view->border == B_NONE || !view->border_thickness || view->using_csd) { + if (view->border == B_NONE || !view->border_thickness || + view->border == B_CSD) { return WLR_EDGE_NONE; } diff --git a/sway/ipc-json.c b/sway/ipc-json.c index f054ac9ff..df24b812a 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -216,6 +216,8 @@ static const char *describe_container_border(enum sway_container_border border) return "pixel"; case B_NORMAL: return "normal"; + case B_CSD: + return "csd"; } return "unknown"; } diff --git a/sway/tree/container.c b/sway/tree/container.c index 53b127b7c..054370552 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -717,7 +717,7 @@ void container_set_geometry_from_floating_view(struct sway_container *con) { size_t border_width = 0; size_t top = 0; - if (!view->using_csd) { + if (view->border != B_CSD) { border_width = view->border_thickness * (view->border != B_NONE); top = view->border == B_NORMAL ? container_titlebar_height() : border_width; diff --git a/sway/tree/view.c b/sway/tree/view.c index e370443ca..916fee3db 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "config.h" #ifdef HAVE_XWAYLAND #include @@ -13,6 +14,7 @@ #include "log.h" #include "sway/criteria.h" #include "sway/commands.h" +#include "sway/decoration.h" #include "sway/desktop/transaction.h" #include "sway/input/cursor.h" #include "sway/ipc-server.h" @@ -231,12 +233,8 @@ void view_autoconfigure(struct sway_view *view) { view->border_top = false; } - enum sway_container_border border = view->border; - if (view->using_csd) { - border = B_NONE; - } - - switch (border) { + switch (view->border) { + case B_CSD: case B_NONE: x = con->x; y = con->y + y_offset; @@ -309,16 +307,17 @@ void view_request_activate(struct sway_view *view) { } } -void view_set_tiled(struct sway_view *view, bool tiled) { - if (!tiled) { - view->using_csd = true; - if (view->impl->has_client_side_decorations) { - view->using_csd = view->impl->has_client_side_decorations(view); - } - } else { - view->using_csd = false; +void view_set_csd(struct sway_view *view, bool enabled) { + if (view->decoration) { + uint32_t mode = enabled ? WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT : + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER; + wlr_log(WLR_INFO, "decoration mode %i", mode); + wlr_server_decoration_set_mode( + view->decoration->wlr_server_decoration, mode); } +} +void view_set_tiled(struct sway_view *view, bool tiled) { if (view->impl->set_tiled) { view->impl->set_tiled(view, tiled); }