diff options
-rw-r--r-- | include/sway/tree/container.h | 4 | ||||
-rw-r--r-- | sway/commands/move.c | 7 | ||||
-rw-r--r-- | sway/commands/resize.c | 27 | ||||
-rw-r--r-- | sway/commands/swap.c | 6 | ||||
-rw-r--r-- | sway/input/seatop_move_tiling.c | 2 | ||||
-rw-r--r-- | sway/tree/arrange.c | 68 | ||||
-rw-r--r-- | sway/tree/container.c | 8 |
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; |