aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/tree/container.h4
-rw-r--r--sway/commands/move.c7
-rw-r--r--sway/commands/resize.c27
-rw-r--r--sway/commands/swap.c6
-rw-r--r--sway/input/seatop_move_tiling.c2
-rw-r--r--sway/tree/arrange.c68
-rw-r--r--sway/tree/container.c8
7 files changed, 85 insertions, 37 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index adeb85ae..4efde640 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -88,6 +88,10 @@ struct sway_container {
double saved_x, saved_y;
double saved_width, saved_height;
+ // The share of the space of parent container this container occupies
+ double width_fraction;
+ double height_fraction;
+
// These are in layout coordinates.
double content_x, content_y;
int content_width, content_height;
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 6fd66f28..2a1993ae 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -131,6 +131,7 @@ static void container_move_to_container_from_direction(
container, index);
}
container->width = container->height = 0;
+ container->width_fraction = container->height_fraction = 0;
}
return;
}
@@ -142,6 +143,7 @@ static void container_move_to_container_from_direction(
0 : destination->children->length;
container_insert_child(destination, container, index);
container->width = container->height = 0;
+ container->width_fraction = container->height_fraction = 0;
return;
}
@@ -163,6 +165,7 @@ static void container_move_to_workspace_from_direction(
struct sway_container *container, struct sway_workspace *workspace,
enum wlr_direction move_dir) {
container->width = container->height = 0;
+ container->width_fraction = container->height_fraction = 0;
if (is_parallel(workspace->layout, move_dir)) {
sway_log(SWAY_DEBUG, "Reparenting container (parallel)");
@@ -206,7 +209,7 @@ static void container_move_to_workspace(struct sway_container *container,
} else {
container_detach(container);
container->width = container->height = 0;
- container->saved_width = container->saved_height = 0;
+ container->width_fraction = container->height_fraction = 0;
workspace_add_tiling(workspace, container);
container_update_representation(container);
}
@@ -234,7 +237,7 @@ static void container_move_to_container(struct sway_container *container,
container_detach(container);
container_remove_gaps(container);
container->width = container->height = 0;
- container->saved_width = container->saved_height = 0;
+ container->width_fraction = container->height_fraction = 0;
if (destination->view) {
container_add_sibling(destination, container, 1);
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index 440937f0..28f2552e 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -174,10 +174,14 @@ void container_resize_tiled(struct sway_container *con,
if (prev && prev->width - sibling_amount < MIN_SANE_W) {
return;
}
- con->width += amount;
- next->width -= sibling_amount;
+
+ con->width_fraction +=
+ ((double)amount / con->width) * con->width_fraction;
+ next->width_fraction -=
+ ((double)sibling_amount / con->width) * con->width_fraction;
if (prev) {
- prev->width -= sibling_amount;
+ prev->width_fraction -=
+ ((double)sibling_amount / con->width) * con->width_fraction;
}
} else {
if (con->height + amount < MIN_SANE_H) {
@@ -189,10 +193,14 @@ void container_resize_tiled(struct sway_container *con,
if (prev && prev->height - sibling_amount < MIN_SANE_H) {
return;
}
- con->height += amount;
- next->height -= sibling_amount;
+
+ con->height_fraction +=
+ ((double)amount / con->height) * con->height_fraction;
+ next->height_fraction -=
+ ((double)sibling_amount / con->height) * con->height_fraction;
if (prev) {
- prev->height -= sibling_amount;
+ prev->height_fraction -=
+ ((double)sibling_amount / con->height) * con->height_fraction;
}
}
@@ -280,10 +288,11 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis,
}
}
- double old_width = current->width;
- double old_height = current->height;
+ double old_width = current->width_fraction;
+ double old_height = current->height_fraction;
container_resize_tiled(current, axis, amount->amount);
- if (current->width == old_width && current->height == old_height) {
+ if (current->width_fraction == old_width &&
+ current->height_fraction == old_height) {
return cmd_results_new(CMD_INVALID, "Cannot resize any further");
}
return cmd_results_new(CMD_SUCCESS, NULL);
diff --git a/sway/commands/swap.c b/sway/commands/swap.c
index f27aa7ed..a4a4108d 100644
--- a/sway/commands/swap.c
+++ b/sway/commands/swap.c
@@ -20,6 +20,8 @@ static void swap_places(struct sway_container *con1,
temp->y = con1->y;
temp->width = con1->width;
temp->height = con1->height;
+ temp->width_fraction = con1->width_fraction;
+ temp->height_fraction = con1->height_fraction;
temp->parent = con1->parent;
temp->workspace = con1->workspace;
@@ -27,11 +29,15 @@ static void swap_places(struct sway_container *con1,
con1->y = con2->y;
con1->width = con2->width;
con1->height = con2->height;
+ con1->width_fraction = con2->width_fraction;
+ con1->height_fraction = con2->height_fraction;
con2->x = temp->x;
con2->y = temp->y;
con2->width = temp->width;
con2->height = temp->height;
+ con2->width_fraction = temp->width_fraction;
+ con2->height_fraction = temp->height_fraction;
int temp_index = container_sibling_index(con1);
if (con2->parent) {
diff --git a/sway/input/seatop_move_tiling.c b/sway/input/seatop_move_tiling.c
index e1506175..4201ae37 100644
--- a/sway/input/seatop_move_tiling.c
+++ b/sway/input/seatop_move_tiling.c
@@ -291,6 +291,8 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
siblings->items[1] : siblings->items[index - 1];
con->width = sibling->width;
con->height = sibling->height;
+ con->width_fraction = sibling->width_fraction;
+ con->height_fraction = sibling->height_fraction;
}
arrange_workspace(old_ws);
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index fc5d49ed..dd0a72cd 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -18,39 +18,49 @@ static void apply_horiz_layout(list_t *children, struct wlr_box *parent) {
return;
}
- // Count the number of new windows we are resizing
+ // Count the number of new windows we are resizing, and how much space
+ // is currently occupied
int new_children = 0;
+ double current_width_fraction = 0;
for (int i = 0; i < children->length; ++i) {
struct sway_container *child = children->items[i];
- if (child->width <= 0) {
+ current_width_fraction += child->width_fraction;
+ if (child->width_fraction <= 0) {
new_children += 1;
}
}
- // Calculate total width of children
- double total_width = 0;
+ // Calculate each height fraction
+ double total_width_fraction = 0;
for (int i = 0; i < children->length; ++i) {
struct sway_container *child = children->items[i];
- if (child->width <= 0) {
- if (children->length > new_children) {
- child->width = parent->width / (children->length - new_children);
+ if (child->width_fraction <= 0) {
+ if (current_width_fraction <= 0) {
+ child->width_fraction = 1.0;
+ } else if (children->length > new_children) {
+ child->width_fraction = current_width_fraction /
+ (children->length - new_children);
} else {
- child->width = parent->width;
+ child->width_fraction = current_width_fraction;
}
}
- container_remove_gaps(child);
- total_width += child->width;
+ total_width_fraction += child->width_fraction;
+ }
+ // Normalize width fractions so the sum is 1.0
+ for (int i = 0; i < children->length; ++i) {
+ struct sway_container *child = children->items[i];
+ child->width_fraction /= total_width_fraction;
}
- double scale = parent->width / total_width;
// Resize windows
sway_log(SWAY_DEBUG, "Arranging %p horizontally", parent);
double child_x = parent->x;
for (int i = 0; i < children->length; ++i) {
struct sway_container *child = children->items[i];
+ container_remove_gaps(child);
child->x = child_x;
child->y = parent->y;
- child->width = floor(child->width * scale);
+ child->width = floor(child->width_fraction * parent->width);
child->height = parent->height;
child_x += child->width;
@@ -67,40 +77,50 @@ static void apply_vert_layout(list_t *children, struct wlr_box *parent) {
return;
}
- // Count the number of new windows we are resizing
+ // Count the number of new windows we are resizing, and how much space
+ // is currently occupied
int new_children = 0;
+ double current_height_fraction = 0;
for (int i = 0; i < children->length; ++i) {
struct sway_container *child = children->items[i];
- if (child->height <= 0) {
+ current_height_fraction += child->height_fraction;
+ if (child->height_fraction <= 0) {
new_children += 1;
}
}
- // Calculate total height of children
- double total_height = 0;
+ // Calculate each height fraction
+ double total_height_fraction = 0;
for (int i = 0; i < children->length; ++i) {
struct sway_container *child = children->items[i];
- if (child->height <= 0) {
- if (children->length > new_children) {
- child->height = parent->height / (children->length - new_children);
+ if (child->height_fraction <= 0) {
+ if (current_height_fraction <= 0) {
+ child->height_fraction = 1.0;
+ } else if (children->length > new_children) {
+ child->height_fraction = current_height_fraction /
+ (children->length - new_children);
} else {
- child->height = parent->height;
+ child->height_fraction = current_height_fraction;
}
}
- container_remove_gaps(child);
- total_height += child->height;
+ total_height_fraction += child->height_fraction;
+ }
+ // Normalize height fractions so the sum is 1.0
+ for (int i = 0; i < children->length; ++i) {
+ struct sway_container *child = children->items[i];
+ child->height_fraction /= total_height_fraction;
}
- double scale = parent->height / total_height;
// Resize
sway_log(SWAY_DEBUG, "Arranging %p vertically", parent);
double child_y = parent->y;
for (int i = 0; i < children->length; ++i) {
struct sway_container *child = children->items[i];
+ container_remove_gaps(child);
child->x = parent->x;
child->y = child_y;
child->width = parent->width;
- child->height = floor(child->height * scale);
+ child->height = floor(child->height_fraction * parent->height);
child_y += child->height;
// Make last child use remaining height of parent
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 9046ae27..068dbb88 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -789,6 +789,8 @@ void container_set_floating(struct sway_container *container, bool enable) {
container->border = container->saved_border;
}
}
+ container->width_fraction = 0;
+ container->height_fraction = 0;
}
container_end_mouse_operation(container);
@@ -1022,9 +1024,9 @@ void container_fullscreen_disable(struct sway_container *con) {
if (container_is_floating(con)) {
con->x = con->saved_x;
con->y = con->saved_y;
+ con->width = con->saved_width;
+ con->height = con->saved_height;
}
- con->width = con->saved_width;
- con->height = con->saved_height;
if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) {
if (con->workspace) {
@@ -1415,6 +1417,8 @@ struct sway_container *container_split(struct sway_container *child,
struct sway_container *cont = container_create(NULL);
cont->width = child->width;
cont->height = child->height;
+ cont->width_fraction = child->width_fraction;
+ cont->height_fraction = child->height_fraction;
cont->x = child->x;
cont->y = child->y;
cont->current_gaps = child->current_gaps;