aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Pedro CĂ´rte-Real <pedro@pedrocr.net>2019-07-06 11:57:32 +0100
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-07-15 23:46:27 -0400
commitd0233af3b39475b47be4248846536811ddca2624 (patch)
treeacc61150bd9e6bc1a69c8e7f38a700e8a9e8b2ed
parentUse -fmacro-prefix-map to strip build path (diff)
downloadsway-d0233af3b39475b47be4248846536811ddca2624.tar.gz
sway-d0233af3b39475b47be4248846536811ddca2624.tar.zst
sway-d0233af3b39475b47be4248846536811ddca2624.zip
Rework gaps code to be simpler and correct
Instead of tracking gaps per child apply gaps in two logical places: 1. In tiled containers use the layout code to add the gaps between windows. This is much simpler and guarantees that the sizing of children is correct. 2. In the workspace itself apply all the gaps around the edge. Here we're in the correct position to size inner and outer gaps correctly and decide on smart gaps in a single location. Fixes #4296
-rw-r--r--include/sway/tree/container.h12
-rw-r--r--sway/commands/move.c1
-rw-r--r--sway/tree/arrange.c55
-rw-r--r--sway/tree/container.c67
-rw-r--r--sway/tree/view.c16
-rw-r--r--sway/tree/workspace.c38
6 files changed, 53 insertions, 136 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h
index 4efde640..099a8089 100644
--- a/include/sway/tree/container.h
+++ b/include/sway/tree/container.h
@@ -116,14 +116,6 @@ struct sway_container {
116 bool border_left; 116 bool border_left;
117 bool border_right; 117 bool border_right;
118 118
119 // The gaps currently applied to the container.
120 struct {
121 int top;
122 int right;
123 int bottom;
124 int left;
125 } current_gaps;
126
127 struct sway_workspace *workspace; // NULL when hidden in the scratchpad 119 struct sway_workspace *workspace; // NULL when hidden in the scratchpad
128 struct sway_container *parent; // NULL if container in root of workspace 120 struct sway_container *parent; // NULL if container in root of workspace
129 list_t *children; // struct sway_container 121 list_t *children; // struct sway_container
@@ -296,10 +288,6 @@ struct sway_output *container_get_effective_output(struct sway_container *con);
296 288
297void container_discover_outputs(struct sway_container *con); 289void container_discover_outputs(struct sway_container *con);
298 290
299void container_remove_gaps(struct sway_container *container);
300
301void container_add_gaps(struct sway_container *container);
302
303enum sway_container_layout container_parent_layout(struct sway_container *con); 291enum sway_container_layout container_parent_layout(struct sway_container *con);
304 292
305enum sway_container_layout container_current_parent_layout( 293enum sway_container_layout container_current_parent_layout(
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 2a1993ae..5779b431 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -235,7 +235,6 @@ static void container_move_to_container(struct sway_container *container,
235 struct sway_workspace *old_workspace = container->workspace; 235 struct sway_workspace *old_workspace = container->workspace;
236 236
237 container_detach(container); 237 container_detach(container);
238 container_remove_gaps(container);
239 container->width = container->height = 0; 238 container->width = container->height = 0;
240 container->width_fraction = container->height_fraction = 0; 239 container->width_fraction = container->height_fraction = 0;
241 240
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index dd0a72cd..caafb1af 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -52,23 +52,39 @@ static void apply_horiz_layout(list_t *children, struct wlr_box *parent) {
52 child->width_fraction /= total_width_fraction; 52 child->width_fraction /= total_width_fraction;
53 } 53 }
54 54
55 // Calculate gap size
56 double inner_gap = 0;
57 struct sway_container *child = children->items[0];
58 struct sway_workspace *ws = child->workspace;
59 if (ws) {
60 inner_gap = ws->gaps_inner;
61 }
62 // Descendants of tabbed/stacked containers don't have gaps
63 struct sway_container *temp = child;
64 while (temp) {
65 enum sway_container_layout layout = container_parent_layout(temp);
66 if (layout == L_TABBED || layout == L_STACKED) {
67 inner_gap = 0;
68 }
69 temp = temp->parent;
70 }
71 double child_total_width = parent->width - inner_gap * (children->length - 1);
72
55 // Resize windows 73 // Resize windows
56 sway_log(SWAY_DEBUG, "Arranging %p horizontally", parent); 74 sway_log(SWAY_DEBUG, "Arranging %p horizontally", parent);
57 double child_x = parent->x; 75 double child_x = parent->x;
58 for (int i = 0; i < children->length; ++i) { 76 for (int i = 0; i < children->length; ++i) {
59 struct sway_container *child = children->items[i]; 77 struct sway_container *child = children->items[i];
60 container_remove_gaps(child);
61 child->x = child_x; 78 child->x = child_x;
62 child->y = parent->y; 79 child->y = parent->y;
63 child->width = floor(child->width_fraction * parent->width); 80 child->width = floor(child->width_fraction * child_total_width);
64 child->height = parent->height; 81 child->height = parent->height;
65 child_x += child->width; 82 child_x += child->width + inner_gap;
66 83
67 // Make last child use remaining width of parent 84 // Make last child use remaining width of parent
68 if (i == children->length - 1) { 85 if (i == children->length - 1) {
69 child->width = parent->x + parent->width - child->x; 86 child->width = parent->x + parent->width - child->x;
70 } 87 }
71 container_add_gaps(child);
72 } 88 }
73} 89}
74 90
@@ -111,23 +127,39 @@ static void apply_vert_layout(list_t *children, struct wlr_box *parent) {
111 child->height_fraction /= total_height_fraction; 127 child->height_fraction /= total_height_fraction;
112 } 128 }
113 129
114 // Resize 130 // Calculate gap size
131 double inner_gap = 0;
132 struct sway_container *child = children->items[0];
133 struct sway_workspace *ws = child->workspace;
134 if (ws) {
135 inner_gap = ws->gaps_inner;
136 }
137 // Descendants of tabbed/stacked containers don't have gaps
138 struct sway_container *temp = child;
139 while (temp) {
140 enum sway_container_layout layout = container_parent_layout(temp);
141 if (layout == L_TABBED || layout == L_STACKED) {
142 inner_gap = 0;
143 }
144 temp = temp->parent;
145 }
146 double child_total_height = parent->height - inner_gap * (children->length - 1);
147
148 // Resize windows
115 sway_log(SWAY_DEBUG, "Arranging %p vertically", parent); 149 sway_log(SWAY_DEBUG, "Arranging %p vertically", parent);
116 double child_y = parent->y; 150 double child_y = parent->y;
117 for (int i = 0; i < children->length; ++i) { 151 for (int i = 0; i < children->length; ++i) {
118 struct sway_container *child = children->items[i]; 152 struct sway_container *child = children->items[i];
119 container_remove_gaps(child);
120 child->x = parent->x; 153 child->x = parent->x;
121 child->y = child_y; 154 child->y = child_y;
122 child->width = parent->width; 155 child->width = parent->width;
123 child->height = floor(child->height_fraction * parent->height); 156 child->height = floor(child->height_fraction * child_total_height);
124 child_y += child->height; 157 child_y += child->height + inner_gap;
125 158
126 // Make last child use remaining height of parent 159 // Make last child use remaining height of parent
127 if (i == children->length - 1) { 160 if (i == children->length - 1) {
128 child->height = parent->y + parent->height - child->y; 161 child->height = parent->y + parent->height - child->y;
129 } 162 }
130 container_add_gaps(child);
131 } 163 }
132} 164}
133 165
@@ -138,12 +170,10 @@ static void apply_tabbed_layout(list_t *children, struct wlr_box *parent) {
138 for (int i = 0; i < children->length; ++i) { 170 for (int i = 0; i < children->length; ++i) {
139 struct sway_container *child = children->items[i]; 171 struct sway_container *child = children->items[i];
140 int parent_offset = child->view ? 0 : container_titlebar_height(); 172 int parent_offset = child->view ? 0 : container_titlebar_height();
141 container_remove_gaps(child);
142 child->x = parent->x; 173 child->x = parent->x;
143 child->y = parent->y + parent_offset; 174 child->y = parent->y + parent_offset;
144 child->width = parent->width; 175 child->width = parent->width;
145 child->height = parent->height - parent_offset; 176 child->height = parent->height - parent_offset;
146 container_add_gaps(child);
147 } 177 }
148} 178}
149 179
@@ -155,12 +185,10 @@ static void apply_stacked_layout(list_t *children, struct wlr_box *parent) {
155 struct sway_container *child = children->items[i]; 185 struct sway_container *child = children->items[i];
156 int parent_offset = child->view ? 0 : 186 int parent_offset = child->view ? 0 :
157 container_titlebar_height() * children->length; 187 container_titlebar_height() * children->length;
158 container_remove_gaps(child);
159 child->x = parent->x; 188 child->x = parent->x;
160 child->y = parent->y + parent_offset; 189 child->y = parent->y + parent_offset;
161 child->width = parent->width; 190 child->width = parent->width;
162 child->height = parent->height - parent_offset; 191 child->height = parent->height - parent_offset;
163 container_add_gaps(child);
164 } 192 }
165} 193}
166 194
@@ -226,7 +254,6 @@ void arrange_workspace(struct sway_workspace *workspace) {
226 struct wlr_box *area = &output->usable_area; 254 struct wlr_box *area = &output->usable_area;
227 sway_log(SWAY_DEBUG, "Usable area for ws: %dx%d@%d,%d", 255 sway_log(SWAY_DEBUG, "Usable area for ws: %dx%d@%d,%d",
228 area->width, area->height, area->x, area->y); 256 area->width, area->height, area->x, area->y);
229 workspace_remove_gaps(workspace);
230 257
231 bool first_arrange = workspace->width == 0 && workspace->height == 0; 258 bool first_arrange = workspace->width == 0 && workspace->height == 0;
232 double prev_x = workspace->x; 259 double prev_x = workspace->x;
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 068dbb88..10aed599 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -1173,72 +1173,6 @@ void container_discover_outputs(struct sway_container *con) {
1173 } 1173 }
1174} 1174}
1175 1175
1176void container_remove_gaps(struct sway_container *c) {
1177 if (c->current_gaps.top == 0 && c->current_gaps.right == 0 &&
1178 c->current_gaps.bottom == 0 && c->current_gaps.left == 0) {
1179 return;
1180 }
1181
1182 c->width += c->current_gaps.left + c->current_gaps.right;
1183 c->height += c->current_gaps.top + c->current_gaps.bottom;
1184 c->x -= c->current_gaps.left;
1185 c->y -= c->current_gaps.top;
1186
1187 c->current_gaps.top = 0;
1188 c->current_gaps.right = 0;
1189 c->current_gaps.bottom = 0;
1190 c->current_gaps.left = 0;
1191}
1192
1193void container_add_gaps(struct sway_container *c) {
1194 if (c->current_gaps.top > 0 || c->current_gaps.right > 0 ||
1195 c->current_gaps.bottom > 0 || c->current_gaps.left > 0) {
1196 return;
1197 }
1198 // Fullscreen global scratchpad containers cannot have gaps
1199 struct sway_workspace *ws = c->workspace;
1200 if (!ws) {
1201 return;
1202 }
1203 // Linear containers don't have gaps because it'd create double gaps
1204 if (!c->view && c->layout != L_TABBED && c->layout != L_STACKED) {
1205 return;
1206 }
1207 // Descendants of tabbed/stacked containers re-use the gaps of the container
1208 struct sway_container *temp = c;
1209 while (temp) {
1210 enum sway_container_layout layout = container_parent_layout(temp);
1211 if (layout == L_TABBED || layout == L_STACKED) {
1212 return;
1213 }
1214 temp = temp->parent;
1215 }
1216 // If smart gaps is on, don't add gaps if there is only one view visible
1217 if (config->smart_gaps) {
1218 struct sway_view *view = c->view;
1219 if (!view) {
1220 struct sway_seat *seat =
1221 input_manager_get_default_seat();
1222 struct sway_container *focus =
1223 seat_get_focus_inactive_view(seat, &c->node);
1224 view = focus ? focus->view : NULL;
1225 }
1226 if (view && view_is_only_visible(view)) {
1227 return;
1228 }
1229 }
1230
1231 c->current_gaps.top = c->y == ws->y ? ws->gaps_inner : 0;
1232 c->current_gaps.right = ws->gaps_inner;
1233 c->current_gaps.bottom = ws->gaps_inner;
1234 c->current_gaps.left = c->x == ws->x ? ws->gaps_inner : 0;
1235
1236 c->x += c->current_gaps.left;
1237 c->y += c->current_gaps.top;
1238 c->width -= c->current_gaps.left + c->current_gaps.right;
1239 c->height -= c->current_gaps.top + c->current_gaps.bottom;
1240}
1241
1242enum sway_container_layout container_parent_layout(struct sway_container *con) { 1176enum sway_container_layout container_parent_layout(struct sway_container *con) {
1243 if (con->parent) { 1177 if (con->parent) {
1244 return con->parent->layout; 1178 return con->parent->layout;
@@ -1421,7 +1355,6 @@ struct sway_container *container_split(struct sway_container *child,
1421 cont->height_fraction = child->height_fraction; 1355 cont->height_fraction = child->height_fraction;
1422 cont->x = child->x; 1356 cont->x = child->x;
1423 cont->y = child->y; 1357 cont->y = child->y;
1424 cont->current_gaps = child->current_gaps;
1425 cont->layout = layout; 1358 cont->layout = layout;
1426 1359
1427 container_replace(child, cont); 1360 container_replace(child, cont);
diff --git a/sway/tree/view.c b/sway/tree/view.c
index f6d62ad6..be540804 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -183,14 +183,6 @@ bool view_is_only_visible(struct sway_view *view) {
183} 183}
184 184
185static bool gaps_to_edge(struct sway_view *view) { 185static bool gaps_to_edge(struct sway_view *view) {
186 struct sway_container *con = view->container;
187 while (con) {
188 if (con->current_gaps.top > 0 || con->current_gaps.right > 0 ||
189 con->current_gaps.bottom > 0 || con->current_gaps.left > 0) {
190 return true;
191 }
192 con = con->parent;
193 }
194 struct side_gaps gaps = view->container->workspace->current_gaps; 186 struct side_gaps gaps = view->container->workspace->current_gaps;
195 return gaps.top > 0 || gaps.right > 0 || gaps.bottom > 0 || gaps.left > 0; 187 return gaps.top > 0 || gaps.right > 0 || gaps.bottom > 0 || gaps.left > 0;
196} 188}
@@ -232,14 +224,14 @@ void view_autoconfigure(struct sway_view *view) {
232 224
233 if (config->hide_edge_borders == E_BOTH 225 if (config->hide_edge_borders == E_BOTH
234 || config->hide_edge_borders == E_VERTICAL || hide_smart) { 226 || config->hide_edge_borders == E_VERTICAL || hide_smart) {
235 con->border_left = con->x - con->current_gaps.left != ws->x; 227 con->border_left = con->x != ws->x;
236 int right_x = con->x + con->width + con->current_gaps.right; 228 int right_x = con->x + con->width;
237 con->border_right = right_x != ws->x + ws->width; 229 con->border_right = right_x != ws->x + ws->width;
238 } 230 }
239 if (config->hide_edge_borders == E_BOTH 231 if (config->hide_edge_borders == E_BOTH
240 || config->hide_edge_borders == E_HORIZONTAL || hide_smart) { 232 || config->hide_edge_borders == E_HORIZONTAL || hide_smart) {
241 con->border_top = con->y - con->current_gaps.top != ws->y; 233 con->border_top = con->y != ws->y;
242 int bottom_y = con->y + con->height + con->current_gaps.bottom; 234 int bottom_y = con->y + con->height;
243 con->border_bottom = bottom_y != ws->y + ws->height; 235 con->border_bottom = bottom_y != ws->y + ws->height;
244 } 236 }
245 237
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 914b6a9d..accdf6e3 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -700,28 +700,7 @@ void workspace_insert_tiling(struct sway_workspace *workspace,
700 node_set_dirty(&con->node); 700 node_set_dirty(&con->node);
701} 701}
702 702
703void workspace_remove_gaps(struct sway_workspace *ws) {
704 if (ws->current_gaps.top == 0 && ws->current_gaps.right == 0 &&
705 ws->current_gaps.bottom == 0 && ws->current_gaps.left == 0) {
706 return;
707 }
708
709 ws->width += ws->current_gaps.left + ws->current_gaps.right;
710 ws->height += ws->current_gaps.top + ws->current_gaps.bottom;
711 ws->x -= ws->current_gaps.left;
712 ws->y -= ws->current_gaps.top;
713
714 ws->current_gaps.top = 0;
715 ws->current_gaps.right = 0;
716 ws->current_gaps.bottom = 0;
717 ws->current_gaps.left = 0;
718}
719
720void workspace_add_gaps(struct sway_workspace *ws) { 703void workspace_add_gaps(struct sway_workspace *ws) {
721 if (ws->current_gaps.top > 0 || ws->current_gaps.right > 0 ||
722 ws->current_gaps.bottom > 0 || ws->current_gaps.left > 0) {
723 return;
724 }
725 if (config->smart_gaps) { 704 if (config->smart_gaps) {
726 struct sway_seat *seat = input_manager_get_default_seat(); 705 struct sway_seat *seat = input_manager_get_default_seat();
727 struct sway_container *focus = 706 struct sway_container *focus =
@@ -730,20 +709,19 @@ void workspace_add_gaps(struct sway_workspace *ws) {
730 focus = seat_get_focus_inactive_view(seat, &focus->node); 709 focus = seat_get_focus_inactive_view(seat, &focus->node);
731 } 710 }
732 if (focus && focus->view && view_is_only_visible(focus->view)) { 711 if (focus && focus->view && view_is_only_visible(focus->view)) {
712 ws->current_gaps.top = 0;
713 ws->current_gaps.right = 0;
714 ws->current_gaps.bottom = 0;
715 ws->current_gaps.left = 0;
733 return; 716 return;
734 } 717 }
735 } 718 }
736 719
737 ws->current_gaps = ws->gaps_outer; 720 ws->current_gaps = ws->gaps_outer;
738 if (ws->layout == L_TABBED || ws->layout == L_STACKED) { 721 ws->current_gaps.top += ws->gaps_inner;
739 // We have to add inner gaps for this, because children of tabbed and 722 ws->current_gaps.right += ws->gaps_inner;
740 // stacked containers don't apply their own gaps - they assume the 723 ws->current_gaps.bottom += ws->gaps_inner;
741 // tabbed/stacked container is using gaps. 724 ws->current_gaps.left += ws->gaps_inner;
742 ws->current_gaps.top += ws->gaps_inner;
743 ws->current_gaps.right += ws->gaps_inner;
744 ws->current_gaps.bottom += ws->gaps_inner;
745 ws->current_gaps.left += ws->gaps_inner;
746 }
747 725
748 ws->x += ws->current_gaps.left; 726 ws->x += ws->current_gaps.left;
749 ws->y += ws->current_gaps.top; 727 ws->y += ws->current_gaps.top;