aboutsummaryrefslogtreecommitdiffstats
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 {
88 double saved_x, saved_y; 88 double saved_x, saved_y;
89 double saved_width, saved_height; 89 double saved_width, saved_height;
90 90
91 // The share of the space of parent container this container occupies
92 double width_fraction;
93 double height_fraction;
94
91 // These are in layout coordinates. 95 // These are in layout coordinates.
92 double content_x, content_y; 96 double content_x, content_y;
93 int content_width, content_height; 97 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(
131 container, index); 131 container, index);
132 } 132 }
133 container->width = container->height = 0; 133 container->width = container->height = 0;
134 container->width_fraction = container->height_fraction = 0;
134 } 135 }
135 return; 136 return;
136 } 137 }
@@ -142,6 +143,7 @@ static void container_move_to_container_from_direction(
142 0 : destination->children->length; 143 0 : destination->children->length;
143 container_insert_child(destination, container, index); 144 container_insert_child(destination, container, index);
144 container->width = container->height = 0; 145 container->width = container->height = 0;
146 container->width_fraction = container->height_fraction = 0;
145 return; 147 return;
146 } 148 }
147 149
@@ -163,6 +165,7 @@ static void container_move_to_workspace_from_direction(
163 struct sway_container *container, struct sway_workspace *workspace, 165 struct sway_container *container, struct sway_workspace *workspace,
164 enum wlr_direction move_dir) { 166 enum wlr_direction move_dir) {
165 container->width = container->height = 0; 167 container->width = container->height = 0;
168 container->width_fraction = container->height_fraction = 0;
166 169
167 if (is_parallel(workspace->layout, move_dir)) { 170 if (is_parallel(workspace->layout, move_dir)) {
168 sway_log(SWAY_DEBUG, "Reparenting container (parallel)"); 171 sway_log(SWAY_DEBUG, "Reparenting container (parallel)");
@@ -206,7 +209,7 @@ static void container_move_to_workspace(struct sway_container *container,
206 } else { 209 } else {
207 container_detach(container); 210 container_detach(container);
208 container->width = container->height = 0; 211 container->width = container->height = 0;
209 container->saved_width = container->saved_height = 0; 212 container->width_fraction = container->height_fraction = 0;
210 workspace_add_tiling(workspace, container); 213 workspace_add_tiling(workspace, container);
211 container_update_representation(container); 214 container_update_representation(container);
212 } 215 }
@@ -234,7 +237,7 @@ static void container_move_to_container(struct sway_container *container,
234 container_detach(container); 237 container_detach(container);
235 container_remove_gaps(container); 238 container_remove_gaps(container);
236 container->width = container->height = 0; 239 container->width = container->height = 0;
237 container->saved_width = container->saved_height = 0; 240 container->width_fraction = container->height_fraction = 0;
238 241
239 if (destination->view) { 242 if (destination->view) {
240 container_add_sibling(destination, container, 1); 243 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,
174 if (prev && prev->width - sibling_amount < MIN_SANE_W) { 174 if (prev && prev->width - sibling_amount < MIN_SANE_W) {
175 return; 175 return;
176 } 176 }
177 con->width += amount; 177
178 next->width -= sibling_amount; 178 con->width_fraction +=
179 ((double)amount / con->width) * con->width_fraction;
180 next->width_fraction -=
181 ((double)sibling_amount / con->width) * con->width_fraction;
179 if (prev) { 182 if (prev) {
180 prev->width -= sibling_amount; 183 prev->width_fraction -=
184 ((double)sibling_amount / con->width) * con->width_fraction;
181 } 185 }
182 } else { 186 } else {
183 if (con->height + amount < MIN_SANE_H) { 187 if (con->height + amount < MIN_SANE_H) {
@@ -189,10 +193,14 @@ void container_resize_tiled(struct sway_container *con,
189 if (prev && prev->height - sibling_amount < MIN_SANE_H) { 193 if (prev && prev->height - sibling_amount < MIN_SANE_H) {
190 return; 194 return;
191 } 195 }
192 con->height += amount; 196
193 next->height -= sibling_amount; 197 con->height_fraction +=
198 ((double)amount / con->height) * con->height_fraction;
199 next->height_fraction -=
200 ((double)sibling_amount / con->height) * con->height_fraction;
194 if (prev) { 201 if (prev) {
195 prev->height -= sibling_amount; 202 prev->height_fraction -=
203 ((double)sibling_amount / con->height) * con->height_fraction;
196 } 204 }
197 } 205 }
198 206
@@ -280,10 +288,11 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis,
280 } 288 }
281 } 289 }
282 290
283 double old_width = current->width; 291 double old_width = current->width_fraction;
284 double old_height = current->height; 292 double old_height = current->height_fraction;
285 container_resize_tiled(current, axis, amount->amount); 293 container_resize_tiled(current, axis, amount->amount);
286 if (current->width == old_width && current->height == old_height) { 294 if (current->width_fraction == old_width &&
295 current->height_fraction == old_height) {
287 return cmd_results_new(CMD_INVALID, "Cannot resize any further"); 296 return cmd_results_new(CMD_INVALID, "Cannot resize any further");
288 } 297 }
289 return cmd_results_new(CMD_SUCCESS, NULL); 298 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,
20 temp->y = con1->y; 20 temp->y = con1->y;
21 temp->width = con1->width; 21 temp->width = con1->width;
22 temp->height = con1->height; 22 temp->height = con1->height;
23 temp->width_fraction = con1->width_fraction;
24 temp->height_fraction = con1->height_fraction;
23 temp->parent = con1->parent; 25 temp->parent = con1->parent;
24 temp->workspace = con1->workspace; 26 temp->workspace = con1->workspace;
25 27
@@ -27,11 +29,15 @@ static void swap_places(struct sway_container *con1,
27 con1->y = con2->y; 29 con1->y = con2->y;
28 con1->width = con2->width; 30 con1->width = con2->width;
29 con1->height = con2->height; 31 con1->height = con2->height;
32 con1->width_fraction = con2->width_fraction;
33 con1->height_fraction = con2->height_fraction;
30 34
31 con2->x = temp->x; 35 con2->x = temp->x;
32 con2->y = temp->y; 36 con2->y = temp->y;
33 con2->width = temp->width; 37 con2->width = temp->width;
34 con2->height = temp->height; 38 con2->height = temp->height;
39 con2->width_fraction = temp->width_fraction;
40 con2->height_fraction = temp->height_fraction;
35 41
36 int temp_index = container_sibling_index(con1); 42 int temp_index = container_sibling_index(con1);
37 if (con2->parent) { 43 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,
291 siblings->items[1] : siblings->items[index - 1]; 291 siblings->items[1] : siblings->items[index - 1];
292 con->width = sibling->width; 292 con->width = sibling->width;
293 con->height = sibling->height; 293 con->height = sibling->height;
294 con->width_fraction = sibling->width_fraction;
295 con->height_fraction = sibling->height_fraction;
294 } 296 }
295 297
296 arrange_workspace(old_ws); 298 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) {
18 return; 18 return;
19 } 19 }
20 20
21 // Count the number of new windows we are resizing 21 // Count the number of new windows we are resizing, and how much space
22 // is currently occupied
22 int new_children = 0; 23 int new_children = 0;
24 double current_width_fraction = 0;
23 for (int i = 0; i < children->length; ++i) { 25 for (int i = 0; i < children->length; ++i) {
24 struct sway_container *child = children->items[i]; 26 struct sway_container *child = children->items[i];
25 if (child->width <= 0) { 27 current_width_fraction += child->width_fraction;
28 if (child->width_fraction <= 0) {
26 new_children += 1; 29 new_children += 1;
27 } 30 }
28 } 31 }
29 32
30 // Calculate total width of children 33 // Calculate each height fraction
31 double total_width = 0; 34 double total_width_fraction = 0;
32 for (int i = 0; i < children->length; ++i) { 35 for (int i = 0; i < children->length; ++i) {
33 struct sway_container *child = children->items[i]; 36 struct sway_container *child = children->items[i];
34 if (child->width <= 0) { 37 if (child->width_fraction <= 0) {
35 if (children->length > new_children) { 38 if (current_width_fraction <= 0) {
36 child->width = parent->width / (children->length - new_children); 39 child->width_fraction = 1.0;
40 } else if (children->length > new_children) {
41 child->width_fraction = current_width_fraction /
42 (children->length - new_children);
37 } else { 43 } else {
38 child->width = parent->width; 44 child->width_fraction = current_width_fraction;
39 } 45 }
40 } 46 }
41 container_remove_gaps(child); 47 total_width_fraction += child->width_fraction;
42 total_width += child->width; 48 }
49 // Normalize width fractions so the sum is 1.0
50 for (int i = 0; i < children->length; ++i) {
51 struct sway_container *child = children->items[i];
52 child->width_fraction /= total_width_fraction;
43 } 53 }
44 double scale = parent->width / total_width;
45 54
46 // Resize windows 55 // Resize windows
47 sway_log(SWAY_DEBUG, "Arranging %p horizontally", parent); 56 sway_log(SWAY_DEBUG, "Arranging %p horizontally", parent);
48 double child_x = parent->x; 57 double child_x = parent->x;
49 for (int i = 0; i < children->length; ++i) { 58 for (int i = 0; i < children->length; ++i) {
50 struct sway_container *child = children->items[i]; 59 struct sway_container *child = children->items[i];
60 container_remove_gaps(child);
51 child->x = child_x; 61 child->x = child_x;
52 child->y = parent->y; 62 child->y = parent->y;
53 child->width = floor(child->width * scale); 63 child->width = floor(child->width_fraction * parent->width);
54 child->height = parent->height; 64 child->height = parent->height;
55 child_x += child->width; 65 child_x += child->width;
56 66
@@ -67,40 +77,50 @@ static void apply_vert_layout(list_t *children, struct wlr_box *parent) {
67 return; 77 return;
68 } 78 }
69 79
70 // Count the number of new windows we are resizing 80 // Count the number of new windows we are resizing, and how much space
81 // is currently occupied
71 int new_children = 0; 82 int new_children = 0;
83 double current_height_fraction = 0;
72 for (int i = 0; i < children->length; ++i) { 84 for (int i = 0; i < children->length; ++i) {
73 struct sway_container *child = children->items[i]; 85 struct sway_container *child = children->items[i];
74 if (child->height <= 0) { 86 current_height_fraction += child->height_fraction;
87 if (child->height_fraction <= 0) {
75 new_children += 1; 88 new_children += 1;
76 } 89 }
77 } 90 }
78 91
79 // Calculate total height of children 92 // Calculate each height fraction
80 double total_height = 0; 93 double total_height_fraction = 0;
81 for (int i = 0; i < children->length; ++i) { 94 for (int i = 0; i < children->length; ++i) {
82 struct sway_container *child = children->items[i]; 95 struct sway_container *child = children->items[i];
83 if (child->height <= 0) { 96 if (child->height_fraction <= 0) {
84 if (children->length > new_children) { 97 if (current_height_fraction <= 0) {
85 child->height = parent->height / (children->length - new_children); 98 child->height_fraction = 1.0;
99 } else if (children->length > new_children) {
100 child->height_fraction = current_height_fraction /
101 (children->length - new_children);
86 } else { 102 } else {
87 child->height = parent->height; 103 child->height_fraction = current_height_fraction;
88 } 104 }
89 } 105 }
90 container_remove_gaps(child); 106 total_height_fraction += child->height_fraction;
91 total_height += child->height; 107 }
108 // Normalize height fractions so the sum is 1.0
109 for (int i = 0; i < children->length; ++i) {
110 struct sway_container *child = children->items[i];
111 child->height_fraction /= total_height_fraction;
92 } 112 }
93 double scale = parent->height / total_height;
94 113
95 // Resize 114 // Resize
96 sway_log(SWAY_DEBUG, "Arranging %p vertically", parent); 115 sway_log(SWAY_DEBUG, "Arranging %p vertically", parent);
97 double child_y = parent->y; 116 double child_y = parent->y;
98 for (int i = 0; i < children->length; ++i) { 117 for (int i = 0; i < children->length; ++i) {
99 struct sway_container *child = children->items[i]; 118 struct sway_container *child = children->items[i];
119 container_remove_gaps(child);
100 child->x = parent->x; 120 child->x = parent->x;
101 child->y = child_y; 121 child->y = child_y;
102 child->width = parent->width; 122 child->width = parent->width;
103 child->height = floor(child->height * scale); 123 child->height = floor(child->height_fraction * parent->height);
104 child_y += child->height; 124 child_y += child->height;
105 125
106 // Make last child use remaining height of parent 126 // 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) {
789 container->border = container->saved_border; 789 container->border = container->saved_border;
790 } 790 }
791 } 791 }
792 container->width_fraction = 0;
793 container->height_fraction = 0;
792 } 794 }
793 795
794 container_end_mouse_operation(container); 796 container_end_mouse_operation(container);
@@ -1022,9 +1024,9 @@ void container_fullscreen_disable(struct sway_container *con) {
1022 if (container_is_floating(con)) { 1024 if (container_is_floating(con)) {
1023 con->x = con->saved_x; 1025 con->x = con->saved_x;
1024 con->y = con->saved_y; 1026 con->y = con->saved_y;
1027 con->width = con->saved_width;
1028 con->height = con->saved_height;
1025 } 1029 }
1026 con->width = con->saved_width;
1027 con->height = con->saved_height;
1028 1030
1029 if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { 1031 if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) {
1030 if (con->workspace) { 1032 if (con->workspace) {
@@ -1415,6 +1417,8 @@ struct sway_container *container_split(struct sway_container *child,
1415 struct sway_container *cont = container_create(NULL); 1417 struct sway_container *cont = container_create(NULL);
1416 cont->width = child->width; 1418 cont->width = child->width;
1417 cont->height = child->height; 1419 cont->height = child->height;
1420 cont->width_fraction = child->width_fraction;
1421 cont->height_fraction = child->height_fraction;
1418 cont->x = child->x; 1422 cont->x = child->x;
1419 cont->y = child->y; 1423 cont->y = child->y;
1420 cont->current_gaps = child->current_gaps; 1424 cont->current_gaps = child->current_gaps;