aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/config.h12
-rw-r--r--include/sway/tree/container.h2
-rw-r--r--include/sway/tree/view.h11
-rw-r--r--sway/commands.c6
-rw-r--r--sway/commands/border.c41
-rw-r--r--sway/commands/client.c79
-rw-r--r--sway/commands/default_border.c27
-rw-r--r--sway/config.c71
-rw-r--r--sway/desktop/output.c205
-rw-r--r--sway/desktop/wl_shell.c1
-rw-r--r--sway/desktop/xdg_shell_v6.c1
-rw-r--r--sway/desktop/xwayland.c2
-rw-r--r--sway/meson.build3
-rw-r--r--sway/tree/arrange.c10
-rw-r--r--sway/tree/view.c60
15 files changed, 452 insertions, 79 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 87123289..a0113e98 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -204,11 +204,11 @@ struct bar_config {
};
struct border_colors {
- uint32_t border;
- uint32_t background;
- uint32_t text;
- uint32_t indicator;
- uint32_t child_border;
+ float border[4];
+ float background[4];
+ float text[4];
+ float indicator[4];
+ float child_border[4];
};
enum edge_border_types {
@@ -338,7 +338,7 @@ struct sway_config {
struct border_colors unfocused;
struct border_colors urgent;
struct border_colors placeholder;
- uint32_t background;
+ float background[4];
} border_colors;
// floating view
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 9c921fc4..d092af49 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -72,8 +72,8 @@ struct sway_container {
// For C_ROOT, this has no meaning
// For C_OUTPUT, this is the output position in layout coordinates
// For other types, this is the position in output-local coordinates
+ // Includes borders
double x, y;
- // does not include borders or gaps.
double width, height;
double saved_width, saved_height;
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index a4ad9971..352a62bc 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -41,9 +41,16 @@ struct sway_view {
struct sway_container *swayc; // NULL for unmapped views
struct wlr_surface *surface; // NULL for unmapped views
+
+ // Geometry of the view itself (excludes borders)
+ double x, y;
int width, height;
+
bool is_fullscreen;
+ enum sway_container_border border;
+ int border_thickness;
+
union {
struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6;
struct wlr_xwayland_surface *wlr_xwayland_surface;
@@ -160,6 +167,8 @@ const char *view_get_instance(struct sway_view *view);
void view_configure(struct sway_view *view, double ox, double oy, int width,
int height);
+void view_autoconfigure(struct sway_view *view);
+
void view_set_activated(struct sway_view *view, bool activated);
void view_set_fullscreen_raw(struct sway_view *view, bool fullscreen);
@@ -184,8 +193,6 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface);
void view_unmap(struct sway_view *view);
-void view_update_position(struct sway_view *view, double ox, double oy);
-
void view_update_size(struct sway_view *view, int width, int height);
void view_child_init(struct sway_view_child *child,
diff --git a/sway/commands.c b/sway/commands.c
index a67bc127..575859c9 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -97,8 +97,13 @@ static struct cmd_handler handlers[] = {
{ "bar", cmd_bar },
{ "bindcode", cmd_bindcode },
{ "bindsym", cmd_bindsym },
+ { "client.focused", cmd_client_focused },
+ { "client.focused_inactive", cmd_client_focused_inactive },
+ { "client.unfocused", cmd_client_unfocused },
+ { "client.urgent", cmd_client_urgent },
{ "exec", cmd_exec },
{ "exec_always", cmd_exec_always },
+ { "default_border", cmd_default_border },
{ "focus_follows_mouse", cmd_focus_follows_mouse },
{ "for_window", cmd_for_window },
{ "fullscreen", cmd_fullscreen },
@@ -162,6 +167,7 @@ static struct cmd_handler config_handlers[] = {
/* Runtime-only commands. Keep alphabetized */
static struct cmd_handler command_handlers[] = {
+ { "border", cmd_border },
{ "exit", cmd_exit },
{ "focus", cmd_focus },
{ "kill", cmd_kill },
diff --git a/sway/commands/border.c b/sway/commands/border.c
new file mode 100644
index 00000000..873abb68
--- /dev/null
+++ b/sway/commands/border.c
@@ -0,0 +1,41 @@
+#include "log.h"
+#include "sway/commands.h"
+#include "sway/config.h"
+#include "sway/tree/container.h"
+#include "sway/tree/view.h"
+
+struct cmd_results *cmd_border(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "border", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+
+ struct sway_container *container =
+ config->handler_context.current_container;
+ if (container->type != C_VIEW) {
+ return cmd_results_new(CMD_INVALID, "border",
+ "Only views can have borders");
+ }
+ struct sway_view *view = container->sway_view;
+
+ if (strcmp(argv[0], "none") == 0) {
+ view->border = B_NONE;
+ } else if (strcmp(argv[0], "normal") == 0) {
+ view->border = B_NORMAL;
+ } else if (strcmp(argv[0], "pixel") == 0) {
+ view->border = B_PIXEL;
+ if (argc == 2) {
+ view->border_thickness = atoi(argv[1]);
+ }
+ } else if (strcmp(argv[0], "toggle") == 0) {
+ view->border = (view->border + 1) % 3;
+ } else {
+ return cmd_results_new(CMD_INVALID, "border",
+ "Expected 'border <none|normal|pixel|toggle>' "
+ "or 'border pixel <px>'");
+ }
+
+ view_autoconfigure(view);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/commands/client.c b/sway/commands/client.c
new file mode 100644
index 00000000..ce519381
--- /dev/null
+++ b/sway/commands/client.c
@@ -0,0 +1,79 @@
+#include "log.h"
+#include "sway/commands.h"
+#include "sway/config.h"
+#include "sway/tree/container.h"
+
+static bool parse_color(char *hexstring, float (*dest)[4]) {
+ if (hexstring[0] != '#') {
+ return false;
+ }
+
+ if (strlen(hexstring) != 7) {
+ return false;
+ }
+
+ ++hexstring;
+ char *end;
+ uint32_t decimal = strtol(hexstring, &end, 16);
+
+ if (*end != '\0') {
+ return false;
+ }
+
+ (*dest)[0] = ((decimal >> 16) & 0xff) / 255.0;
+ (*dest)[1] = ((decimal >> 8) & 0xff) / 255.0;
+ (*dest)[2] = (decimal & 0xff) / 255.0;
+ (*dest)[3] = 1.0;
+ return true;
+}
+
+static struct cmd_results *handle_command(int argc, char **argv,
+ struct border_colors *class, char *cmd_name) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 5))) {
+ return error;
+ }
+
+ if (!parse_color(argv[0], &class->border)) {
+ return cmd_results_new(CMD_INVALID, cmd_name,
+ "Unable to parse border color");
+ }
+
+ if (!parse_color(argv[1], &class->background)) {
+ return cmd_results_new(CMD_INVALID, cmd_name,
+ "Unable to parse background color");
+ }
+
+ if (!parse_color(argv[2], &class->text)) {
+ return cmd_results_new(CMD_INVALID, cmd_name,
+ "Unable to parse text color");
+ }
+
+ if (!parse_color(argv[3], &class->indicator)) {
+ return cmd_results_new(CMD_INVALID, cmd_name,
+ "Unable to parse indicator color");
+ }
+
+ if (!parse_color(argv[4], &class->child_border)) {
+ return cmd_results_new(CMD_INVALID, cmd_name,
+ "Unable to parse child border color");
+ }
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
+
+struct cmd_results *cmd_client_focused(int argc, char **argv) {
+ return handle_command(argc, argv, &config->border_colors.focused, "client.focused");
+}
+
+struct cmd_results *cmd_client_focused_inactive(int argc, char **argv) {
+ return handle_command(argc, argv, &config->border_colors.focused_inactive, "client.focused_inactive");
+}
+
+struct cmd_results *cmd_client_unfocused(int argc, char **argv) {
+ return handle_command(argc, argv, &config->border_colors.unfocused, "client.unfocused");
+}
+
+struct cmd_results *cmd_client_urgent(int argc, char **argv) {
+ return handle_command(argc, argv, &config->border_colors.urgent, "client.urgent");
+}
diff --git a/sway/commands/default_border.c b/sway/commands/default_border.c
new file mode 100644
index 00000000..fcd2c075
--- /dev/null
+++ b/sway/commands/default_border.c
@@ -0,0 +1,27 @@
+#include "log.h"
+#include "sway/commands.h"
+#include "sway/config.h"
+#include "sway/tree/container.h"
+
+struct cmd_results *cmd_default_border(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "default_border", EXPECTED_AT_LEAST, 1))) {
+ return error;
+ }
+
+ if (strcmp(argv[0], "none") == 0) {
+ config->border = B_NONE;
+ } else if (strcmp(argv[0], "normal") == 0) {
+ config->border = B_NORMAL;
+ } else if (strcmp(argv[0], "pixel") == 0) {
+ config->border = B_PIXEL;
+ if (argc == 2) {
+ config->border_thickness = atoi(argv[1]);
+ }
+ } else {
+ return cmd_results_new(CMD_INVALID, "default_border",
+ "Expected 'default_border <none|normal|pixel>' or 'default_border pixel <px>'");
+ }
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/config.c b/sway/config.c
index 90b833ab..ed291450 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -130,6 +130,13 @@ static void destroy_removed_seats(struct sway_config *old_config,
}
}
+static void set_color(float (*dest)[4], uint32_t color) {
+ (*dest)[0] = ((color >> 16) & 0xff) / 255.0;
+ (*dest)[1] = ((color >> 8) & 0xff) / 255.0;
+ (*dest)[2] = (color & 0xff) / 255.0;
+ (*dest)[3] = 1.0;
+}
+
static void config_defaults(struct sway_config *config) {
if (!(config->symbols = create_list())) goto cleanup;
if (!(config->modes = create_list())) goto cleanup;
@@ -162,7 +169,6 @@ static void config_defaults(struct sway_config *config) {
config->default_layout = L_NONE;
config->default_orientation = L_NONE;
if (!(config->font = strdup("monospace 10"))) goto cleanup;
- // TODO: border
//config->font_height = get_font_text_height(config->font);
// floating view
@@ -199,37 +205,38 @@ static void config_defaults(struct sway_config *config) {
config->hide_edge_borders = E_NONE;
// border colors
- config->border_colors.focused.border = 0x4C7899FF;
- config->border_colors.focused.background = 0x285577FF;
- config->border_colors.focused.text = 0xFFFFFFFF;
- config->border_colors.focused.indicator = 0x2E9EF4FF;
- config->border_colors.focused.child_border = 0x285577FF;
-
- config->border_colors.focused_inactive.border = 0x333333FF;
- config->border_colors.focused_inactive.background = 0x5F676AFF;
- config->border_colors.focused_inactive.text = 0xFFFFFFFF;
- config->border_colors.focused_inactive.indicator = 0x484E50FF;
- config->border_colors.focused_inactive.child_border = 0x5F676AFF;
-
- config->border_colors.unfocused.border = 0x333333FF;
- config->border_colors.unfocused.background = 0x222222FF;
- config->border_colors.unfocused.text = 0x888888FF;
- config->border_colors.unfocused.indicator = 0x292D2EFF;
- config->border_colors.unfocused.child_border = 0x222222FF;
-
- config->border_colors.urgent.border = 0x2F343AFF;
- config->border_colors.urgent.background = 0x900000FF;
- config->border_colors.urgent.text = 0xFFFFFFFF;
- config->border_colors.urgent.indicator = 0x900000FF;
- config->border_colors.urgent.child_border = 0x900000FF;
-
- config->border_colors.placeholder.border = 0x000000FF;
- config->border_colors.placeholder.background = 0x0C0C0CFF;
- config->border_colors.placeholder.text = 0xFFFFFFFF;
- config->border_colors.placeholder.indicator = 0x000000FF;
- config->border_colors.placeholder.child_border = 0x0C0C0CFF;
-
- config->border_colors.background = 0xFFFFFFFF;
+ set_color(&config->border_colors.focused.border, 0x4C7899);
+ set_color(&config->border_colors.focused.border, 0x4C7899);
+ set_color(&config->border_colors.focused.background, 0x285577);
+ set_color(&config->border_colors.focused.text, 0xFFFFFF);
+ set_color(&config->border_colors.focused.indicator, 0x2E9EF4);
+ set_color(&config->border_colors.focused.child_border, 0x285577);
+
+ set_color(&config->border_colors.focused_inactive.border, 0x333333);
+ set_color(&config->border_colors.focused_inactive.background, 0x5F676A);
+ set_color(&config->border_colors.focused_inactive.text, 0xFFFFFF);
+ set_color(&config->border_colors.focused_inactive.indicator, 0x484E50);
+ set_color(&config->border_colors.focused_inactive.child_border, 0x5F676A);
+
+ set_color(&config->border_colors.unfocused.border, 0x333333);
+ set_color(&config->border_colors.unfocused.background, 0x222222);
+ set_color(&config->border_colors.unfocused.text, 0x888888);
+ set_color(&config->border_colors.unfocused.indicator, 0x292D2E);
+ set_color(&config->border_colors.unfocused.child_border, 0x222222);
+
+ set_color(&config->border_colors.urgent.border, 0x2F343A);
+ set_color(&config->border_colors.urgent.background, 0x900000);
+ set_color(&config->border_colors.urgent.text, 0xFFFFFF);
+ set_color(&config->border_colors.urgent.indicator, 0x900000);
+ set_color(&config->border_colors.urgent.child_border, 0x900000);
+
+ set_color(&config->border_colors.placeholder.border, 0x000000);
+ set_color(&config->border_colors.placeholder.background, 0x0C0C0C);
+ set_color(&config->border_colors.placeholder.text, 0xFFFFFF);
+ set_color(&config->border_colors.placeholder.indicator, 0x000000);
+ set_color(&config->border_colors.placeholder.child_border, 0x0C0C0C);
+
+ set_color(&config->border_colors.background, 0xFFFFFF);
// Security
if (!(config->command_policies = create_list())) goto cleanup;
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index d9ae890f..2511c610 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -116,8 +116,8 @@ static void surface_for_each_surface(struct wlr_surface *surface,
static void output_view_for_each_surface(struct sway_view *view,
struct root_geometry *geo, wlr_surface_iterator_func_t iterator,
void *user_data) {
- geo->x = view->swayc->x;
- geo->y = view->swayc->y;
+ geo->x = view->x;
+ geo->y = view->y;
geo->width = view->surface->current->width;
geo->height = view->surface->current->height;
geo->rotation = 0; // TODO
@@ -217,23 +217,198 @@ static void render_unmanaged(struct sway_output *output,
render_surface_iterator, &data);
}
-static void render_container_iterator(struct sway_container *con,
- void *_data) {
- struct sway_output *output = _data;
- if (!sway_assert(con->type == C_VIEW, "expected a view")) {
- return;
+static void render_view(struct sway_view *view, struct sway_output *output) {
+ struct render_data data = { .output = output, .alpha = view->swayc->alpha };
+ output_view_for_each_surface(
+ view, &data.root_geo, render_surface_iterator, &data);
+}
+
+/**
+ * Render decorations for a view with "border normal".
+ */
+static void render_container_simple_border_normal(struct sway_output *output,
+ struct sway_container *con, struct border_colors *colors) {
+ struct wlr_renderer *renderer =
+ wlr_backend_get_renderer(output->wlr_output->backend);
+ struct wlr_box box;
+ float color[4];
+ color[3] = con->alpha;
+
+ // Child border - left edge
+ memcpy(&color, colors->child_border, sizeof(float) * 3);
+ box.x = con->x;
+ box.y = con->y + 1;
+ box.width = con->sway_view->border_thickness;
+ box.height = con->height - 1;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Child border - right edge
+ box.x = con->x + con->width - con->sway_view->border_thickness;
+ box.y = con->y + 1;
+ box.width = con->sway_view->border_thickness;
+ box.height = con->height - 1;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Child border - bottom edge
+ box.x = con->x;
+ box.y = con->y + con->height - con->sway_view->border_thickness;
+ box.width = con->width;
+ box.height = con->sway_view->border_thickness;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Single pixel bar above title
+ memcpy(&color, colors->border, sizeof(float) * 3);
+ box.x = con->x;
+ box.y = con->y;
+ box.width = con->width;
+ box.height = 1;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Single pixel bar below title
+ box.x = con->x + con->sway_view->border_thickness;
+ box.y = con->sway_view->y - 1;
+ box.width = con->width - con->sway_view->border_thickness * 2;
+ box.height = 1;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Title background
+ memcpy(&color, colors->background, sizeof(float) * 3);
+ box.x = con->x + con->sway_view->border_thickness;
+ box.y = con->y + 1;
+ box.width = con->width - con->sway_view->border_thickness * 2;
+ box.height = con->sway_view->y - con->y - 2;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Title text
+ // TODO
+}
+
+/**
+ * Render decorations for a view with "border pixel".
+ */
+static void render_container_simple_border_pixel(struct sway_output *output,
+ struct sway_container *con, struct border_colors *colors) {
+ struct wlr_renderer *renderer =
+ wlr_backend_get_renderer(output->wlr_output->backend);
+ struct wlr_box box;
+ float color[4];
+ color[3] = con->alpha;
+
+ // Child border - left edge
+ memcpy(&color, colors->child_border, sizeof(float) * 3);
+ box.x = con->x;
+ box.y = con->y;
+ box.width = con->sway_view->border_thickness;
+ box.height = con->height;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Child border - right edge
+ box.x = con->x + con->width - con->sway_view->border_thickness;
+ box.y = con->y;
+ box.width = con->sway_view->border_thickness;
+ box.height = con->height;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Child border - top edge
+ box.x = con->x;
+ box.y = con->y;
+ box.width = con->width;
+ box.height = con->sway_view->border_thickness;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+
+ // Child border - bottom edge
+ box.x = con->x;
+ box.y = con->y + con->height - con->sway_view->border_thickness;
+ box.width = con->width;
+ box.height = con->sway_view->border_thickness;
+ wlr_render_rect(renderer, &box, color,
+ output->wlr_output->transform_matrix);
+}
+
+static void render_container(struct sway_output *output,
+ struct sway_container *con);
+
+/**
+ * Render a container's children using a L_HORIZ or L_VERT layout.
+ *
+ * Wrap child views in borders and leave child containers borderless because
+ * they'll apply their own borders to their children.
+ */
+static void render_container_simple(struct sway_output *output,
+ struct sway_container *con) {
+ struct sway_seat *seat = input_manager_current_seat(input_manager);
+ struct sway_container *focus = seat_get_focus(seat);
+
+ for (int i = 0; i < con->children->length; ++i) {
+ struct sway_container *child = con->children->items[i];
+
+ if (child->type == C_VIEW) {
+ if (child->sway_view->border != B_NONE) {
+ struct border_colors *colors;
+ if (focus == child) {
+ colors = &config->border_colors.focused;
+ } else if (seat_get_focus_inactive(seat, con) == child) {
+ colors = &config->border_colors.focused_inactive;
+ } else {
+ colors = &config->border_colors.unfocused;
+ }
+
+ if (child->sway_view->border == B_NORMAL) {
+ render_container_simple_border_normal(output, child,
+ colors);
+ } else {
+ render_container_simple_border_pixel(output, child, colors);
+ }
+ }
+ render_view(child->sway_view, output);
+ } else {
+ render_container(output, child);
+ }
}
- struct render_data data = { .output = output, .alpha = con->alpha };
- output_view_for_each_surface(con->sway_view, &data.root_geo,
- render_surface_iterator, &data);
+}
+
+/**
+ * Render a container's children using the L_TABBED layout.
+ */
+static void render_container_tabbed(struct sway_output *output,
+ struct sway_container *con) {
+ // TODO
+}
+
+/**
+ * Render a container's children using the L_STACKED layout.
+ */
+static void render_container_stacked(struct sway_output *output,
+ struct sway_container *con) {
+ // TODO
}
static void render_container(struct sway_output *output,
struct sway_container *con) {
- if (con->type == C_VIEW) { // Happens if a view is fullscreened
- render_container_iterator(con, output);
- } else {
- container_descendants(con, C_VIEW, render_container_iterator, output);
+ switch (con->layout) {
+ case L_NONE:
+ case L_HORIZ:
+ case L_VERT:
+ render_container_simple(output, con);
+ break;
+ case L_STACKED:
+ render_container_stacked(output, con);
+ break;
+ case L_TABBED:
+ render_container_tabbed(output, con);
+ break;
+ case L_FLOATING:
+ // TODO
+ break;
}
}
@@ -282,7 +457,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
wlr_renderer_clear(renderer, clear_color);
// TODO: handle views smaller than the output
- render_container(output, workspace->sway_workspace->fullscreen->swayc);
+ render_view(workspace->sway_workspace->fullscreen, output);
if (workspace->sway_workspace->fullscreen->type == SWAY_VIEW_XWAYLAND) {
render_unmanaged(output,
diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c
index 2d666d95..e97a898e 100644
--- a/sway/desktop/wl_shell.c
+++ b/sway/desktop/wl_shell.c
@@ -40,7 +40,6 @@ static void configure(struct sway_view *view, double ox, double oy, int width,
if (wl_shell_view == NULL) {
return;
}
- view_update_position(view, ox, oy);
wl_shell_view->pending_width = width;
wl_shell_view->pending_height = height;
wlr_wl_shell_surface_configure(view->wlr_wl_shell_surface, 0, width, height);
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c
index 2aaedd6c..94556231 100644
--- a/sway/desktop/xdg_shell_v6.c
+++ b/sway/desktop/xdg_shell_v6.c
@@ -102,7 +102,6 @@ static void configure(struct sway_view *view, double ox, double oy, int width,
return;
}
- view_update_position(view, ox, oy);
xdg_shell_v6_view->pending_width = width;
xdg_shell_v6_view->pending_height = height;
wlr_xdg_toplevel_v6_set_size(view->wlr_xdg_surface_v6, width, height);
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index aa9e1797..28f93d6e 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -163,8 +163,6 @@ static void configure(struct sway_view *view, double ox, double oy, int width,
return;
}
- view_update_position(view, ox, oy);
-
xwayland_view->pending_width = width;
xwayland_view->pending_height = height;
wlr_xwayland_surface_configure(xsurface, ox + loutput->x, oy + loutput->y,
diff --git a/sway/meson.build b/sway/meson.build
index 146ad4b8..83e8e656 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -29,6 +29,9 @@ sway_sources = files(
'commands/assign.c',
'commands/bar.c',
'commands/bind.c',
+ 'commands/border.c',
+ 'commands/client.c',
+ 'commands/default_border.c',
'commands/default_orientation.c',
'commands/exit.c',
'commands/exec.c',
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index e1f3ad13..83bb20fb 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -174,12 +174,7 @@ void arrange_children_of(struct sway_container *parent) {
}
if (workspace->sway_workspace->fullscreen) {
// Just arrange the fullscreen view and jump out
- struct sway_container *view =
- workspace->sway_workspace->fullscreen->swayc;
- view_configure(view->sway_view, 0, 0,
- workspace->parent->width, workspace->parent->height);
- view->width = workspace->parent->width;
- view->height = workspace->parent->height;
+ view_autoconfigure(workspace->sway_workspace->fullscreen);
return;
}
@@ -204,8 +199,7 @@ void arrange_children_of(struct sway_container *parent) {
for (int i = 0; i < parent->children->length; ++i) {
struct sway_container *child = parent->children->items[i];
if (child->type == C_VIEW) {
- view_configure(child->sway_view, child->x, child->y,
- child->width, child->height);
+ view_autoconfigure(child->sway_view);
} else {
arrange_children_of(child);
}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index e0aa6c0c..26e1a108 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <wayland-server.h>
+#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_output_layout.h>
#include "log.h"
#include "sway/criteria.h"
@@ -73,6 +74,51 @@ void view_configure(struct sway_view *view, double ox, double oy, int width,
}
}
+/**
+ * Configure the view's position and size based on the swayc's position and
+ * size, taking borders into consideration.
+ */
+void view_autoconfigure(struct sway_view *view) {
+ if (!sway_assert(view->swayc,
+ "Called view_autoconfigure() on a view without a swayc")) {
+ return;
+ }
+
+ if (view->is_fullscreen) {
+ struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
+ view_configure(view, 0, 0, output->width, output->height);
+ view->x = view->y = 0;
+ return;
+ }
+
+ double x, y, width, height;
+ switch (view->border) {
+ case B_NONE:
+ x = view->swayc->x;
+ y = view->swayc->y;
+ width = view->swayc->width;
+ height = view->swayc->height;
+ break;
+ case B_PIXEL:
+ x = view->swayc->x + view->border_thickness;
+ y = view->swayc->y + view->border_thickness;
+ width = view->swayc->width - view->border_thickness * 2;
+ height = view->swayc->height - view->border_thickness * 2;
+ break;
+ case B_NORMAL:
+ // TODO: Size the title bar by checking the font
+ x = view->swayc->x + view->border_thickness;
+ y = view->swayc->y + 20;
+ width = view->swayc->width - view->border_thickness * 2;
+ height = view->swayc->height - view->border_thickness - 20;
+ break;
+ }
+
+ view->x = x;
+ view->y = y;
+ view_configure(view, x, y, width, height);
+}
+
void view_set_activated(struct sway_view *view, bool activated) {
if (view->impl->set_activated) {
view->impl->set_activated(view, activated);
@@ -262,6 +308,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
view->surface = wlr_surface;
view->swayc = cont;
+ view->border = config->border;
+ view->border_thickness = config->border_thickness;
view_init_subsurfaces(view, wlr_surface);
wl_signal_add(&wlr_surface->events.new_subsurface,
@@ -305,23 +353,13 @@ void view_unmap(struct sway_view *view) {
arrange_children_of(parent);
}
-void view_update_position(struct sway_view *view, double ox, double oy) {
- if (view->swayc->x == ox && view->swayc->y == oy) {
- return;
- }
-
- view_damage(view, true);
- view->swayc->x = ox;
- view->swayc->y = oy;
- view_damage(view, true);
-}
-
void view_update_size(struct sway_view *view, int width, int height) {
if (view->width == width && view->height == height) {
return;
}
view_damage(view, true);
+ // Should we update the swayc width/height here too?
view->width = width;
view->height = height;
view_damage(view, true);