aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@users.noreply.github.com>2022-11-12 14:08:13 +0100
committerGitHub <noreply@github.com>2022-11-12 14:08:13 +0100
commitd1301262048592390ff2e8e3bbc2300cd77bd917 (patch)
tree041cf3db9e0a479e33dff773d43a87dfbc29f0a5
parent2b236955bd0dbe8a8a7322ecfd59304d6a7e92b8 (diff)
downloadi3-d1301262048592390ff2e8e3bbc2300cd77bd917.tar.gz
i3-d1301262048592390ff2e8e3bbc2300cd77bd917.zip
gaps: fix inner gaps for stacked/tabbed containers in splith/splitv (#5275)
Fixes https://github.com/i3/i3/issues/5261
-rw-r--r--include/con.h6
-rw-r--r--src/con.c15
-rw-r--r--src/gaps.c23
-rw-r--r--testcases/t/319-gaps.t39
4 files changed, 75 insertions, 8 deletions
diff --git a/include/con.h b/include/con.h
index f97ddaec..e1bb6813 100644
--- a/include/con.h
+++ b/include/con.h
@@ -565,3 +565,9 @@ uint32_t con_rect_size_in_orientation(Con *con);
*
*/
void con_merge_into(Con *old, Con *new);
+
+/**
+ * Returns true if the container is within any stacked/tabbed split container.
+ *
+ */
+bool con_inside_stacked_or_tabbed(Con *con);
diff --git a/src/con.c b/src/con.c
index 47f75167..5bf559a1 100644
--- a/src/con.c
+++ b/src/con.c
@@ -2579,3 +2579,18 @@ void con_merge_into(Con *old, Con *new) {
tree_close_internal(old, DONT_KILL_WINDOW, false);
}
+
+/*
+ * Returns true if the container is within any stacked/tabbed split container.
+ *
+ */
+bool con_inside_stacked_or_tabbed(Con *con) {
+ if (con->parent == NULL) {
+ return false;
+ }
+ if (con->parent->layout == L_STACKED ||
+ con->parent->layout == L_TABBED) {
+ return true;
+ }
+ return con_inside_stacked_or_tabbed(con->parent);
+}
diff --git a/src/gaps.c b/src/gaps.c
index 3babe2b3..545c8b65 100644
--- a/src/gaps.c
+++ b/src/gaps.c
@@ -47,20 +47,27 @@ gaps_t calculate_effective_gaps(Con *con) {
* Decides whether the container should be inset.
*/
bool gaps_should_inset_con(Con *con, int children) {
+ /* No parent? None of the conditionals below can be true. */
+ if (con->parent == NULL) {
+ return false;
+ }
+
+ const bool leaf_or_stacked_tabbed =
+ con_is_leaf(con) ||
+ (con->layout == L_STACKED || con->layout == L_TABBED);
+
/* Inset direct children of the workspace that are leaf containers or
stacked/tabbed containers. */
- if (con->parent != NULL &&
- con->parent->type == CT_WORKSPACE &&
- (con_is_leaf(con) ||
- (con->layout == L_STACKED || con->layout == L_TABBED))) {
+ if (leaf_or_stacked_tabbed &&
+ con->parent->type == CT_WORKSPACE) {
return true;
}
/* Inset direct children of vertical or horizontal split containers at any
- depth in the tree (only leaf containers, not split containers within
- split containers, to avoid double insets). */
- if (con_is_leaf(con) &&
- con->parent != NULL &&
+ depth in the tree. Do not inset as soon as any parent is a stacked or
+ tabbed container, to avoid double insets. */
+ if (leaf_or_stacked_tabbed &&
+ !con_inside_stacked_or_tabbed(con) &&
con->parent->type == CT_CON &&
(con->parent->layout == L_SPLITH ||
con->parent->layout == L_SPLITV)) {
diff --git a/testcases/t/319-gaps.t b/testcases/t/319-gaps.t
index 8bb610b7..1747c37d 100644
--- a/testcases/t/319-gaps.t
+++ b/testcases/t/319-gaps.t
@@ -163,4 +163,43 @@ is_gaps();
exit_gracefully($pid);
+################################################################################
+# Ensure stacked/tabbed containers are properly inset even when they are part
+# of a splith/splitv container (issue #5261).
+################################################################################
+
+$config = <<EOT;
+# i3 config file (v4)
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
+
+gaps inner 10
+
+default_border pixel 0
+EOT
+
+$pid = launch_with_config($config);
+
+fresh_workspace;
+
+my $helper = open_window;
+$right = open_window;
+sync_with_i3;
+cmd 'focus left';
+cmd 'splitv';
+$left = open_window;
+sync_with_i3;
+cmd 'splith';
+cmd 'layout stacked';
+sync_with_i3;
+$helper->destroy;
+sync_with_i3;
+
+$inner_gaps = 10;
+$outer_gaps = 0;
+$total_gaps = $outer_gaps + $inner_gaps;
+
+is_gaps();
+
+exit_gracefully($pid);
+
done_testing;