diff --git a/i3/b660d6a902cf44be22c434101dd2a4e6743e26bc.patch b/i3/b660d6a902cf44be22c434101dd2a4e6743e26bc.patch new file mode 100644 index 0000000..ec4086c --- /dev/null +++ b/i3/b660d6a902cf44be22c434101dd2a4e6743e26bc.patch @@ -0,0 +1,454 @@ +From b660d6a902cf44be22c434101dd2a4e6743e26bc Mon Sep 17 00:00:00 2001 +From: sethpollen +Date: Mon, 22 Jan 2024 13:34:40 -0600 +Subject: [PATCH] Add support for _NET_WM_STATE_MAXIMIZED_{HORZ, VERT} (#5840) + +If a window occupies the entirety of its workspace vertically and/or horizontally, pass it the _NET_WM_STATE_MAXIMIZED_{HORZ, VERT} atoms. This helps applications like Google Chrome draw the tab bar correctly and handle tab clicks correctly (see https://crbug.com/1495853). + +This change is based on work from @yshui in #2380. +--- + include/con.h | 16 +++ + include/i3-atoms_NET_SUPPORTED.xmacro.h | 2 + + .../changes/2-net-wrm-state-maximized | 1 + + src/con.c | 59 ++++++++++ + src/x.c | 41 +++++++ + testcases/lib/i3test.pm.in | 15 +-- + testcases/t/158-wm_take_focus.t | 7 +- + testcases/t/283-net-wm-state-hidden.t | 23 +--- + testcases/t/295-net-wm-state-focused.t | 15 ++- + testcases/t/551-net-wm-state-maximized.t | 104 ++++++++++++++++++ + 10 files changed, 245 insertions(+), 38 deletions(-) + create mode 100644 release-notes/changes/2-net-wrm-state-maximized + create mode 100644 testcases/t/551-net-wm-state-maximized.t + +diff --git a/include/con.h b/include/con.h +index e1bb6813af..52f588b8bc 100644 +--- a/include/con.h ++++ b/include/con.h +@@ -83,6 +83,22 @@ bool con_is_split(Con *con); + */ + bool con_is_hidden(Con *con); + ++/** ++ * Returns true if the container is maximized in the given orientation. ++ * ++ * If the container is floating or fullscreen, it is not considered maximized. ++ * Otherwise, it is maximized if it doesn't share space with any other ++ * container in the given orientation. For example, if a workspace contains ++ * a single splitv container with three children, none of them are considered ++ * vertically maximized, but they are all considered horizontally maximized. ++ * ++ * Passing "maximized" hints to the application can help it make the right ++ * choices about how to draw its borders. See discussion in ++ * https://github.com/i3/i3/pull/2380. ++ * ++ */ ++bool con_is_maximized(Con *con, orientation_t orientation); ++ + /** + * Returns whether the container or any of its children is sticky. + * +diff --git a/include/i3-atoms_NET_SUPPORTED.xmacro.h b/include/i3-atoms_NET_SUPPORTED.xmacro.h +index b491da98a6..90d03c20e0 100644 +--- a/include/i3-atoms_NET_SUPPORTED.xmacro.h ++++ b/include/i3-atoms_NET_SUPPORTED.xmacro.h +@@ -11,6 +11,8 @@ xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) \ + xmacro(_NET_WM_STATE_MODAL) \ + xmacro(_NET_WM_STATE_HIDDEN) \ + xmacro(_NET_WM_STATE_FOCUSED) \ ++xmacro(_NET_WM_STATE_MAXIMIZED_VERT) \ ++xmacro(_NET_WM_STATE_MAXIMIZED_HORZ) \ + xmacro(_NET_WM_STATE) \ + xmacro(_NET_WM_WINDOW_TYPE) \ + xmacro(_NET_WM_WINDOW_TYPE_NORMAL) \ +diff --git a/release-notes/changes/2-net-wrm-state-maximized b/release-notes/changes/2-net-wrm-state-maximized +new file mode 100644 +index 0000000000..1a3268c55d +--- /dev/null ++++ b/release-notes/changes/2-net-wrm-state-maximized +@@ -0,0 +1 @@ ++pass _NET_WM_STATE_MAXIMIZED_{HORZ, VERT} to tiled windows +diff --git a/src/con.c b/src/con.c +index 5ecc270073..72f3ad6e22 100644 +--- a/src/con.c ++++ b/src/con.c +@@ -419,6 +419,65 @@ bool con_is_hidden(Con *con) { + return false; + } + ++/* ++ * Returns true if the container is maximized in the given orientation. ++ * ++ * If the container is floating or fullscreen, it is not considered maximized. ++ * Otherwise, it is maximized if it doesn't share space with any other ++ * container in the given orientation. For example, if a workspace contains ++ * a single splitv container with three children, none of them are considered ++ * vertically maximized, but they are all considered horizontally maximized. ++ * ++ * Passing "maximized" hints to the application can help it make the right ++ * choices about how to draw its borders. See discussion in ++ * https://github.com/i3/i3/pull/2380. ++ */ ++bool con_is_maximized(Con *con, orientation_t orientation) { ++ /* Fullscreen containers are not considered maximized. */ ++ if (con->fullscreen_mode != CF_NONE) { ++ return false; ++ } ++ ++ /* Look up the container layout which corresponds to the given ++ * orientation. */ ++ layout_t layout; ++ switch (orientation) { ++ case HORIZ: ++ layout = L_SPLITH; ++ break; ++ case VERT: ++ layout = L_SPLITV; ++ break; ++ default: ++ assert(false); ++ } ++ ++ /* Go through all parents, stopping once we reach the workspace node. */ ++ Con *current = con; ++ while (true) { ++ Con *parent = current->parent; ++ if (parent == NULL || parent->type == CT_WORKSPACE) { ++ /* We are done searching. We found no reason that the container ++ * should not be considered maximized. */ ++ return true; ++ } ++ ++ if (parent->layout == layout && con_num_children(parent) > 1) { ++ /* The parent has a split in the indicated direction, which ++ * means none of its children are maximized in that direction. */ ++ return false; ++ } ++ ++ /* Floating containers and their children are not considered ++ * maximized. */ ++ if (parent->type == CT_FLOATING_CON) { ++ return false; ++ } ++ ++ current = parent; ++ } ++} ++ + /* + * Returns whether the container or any of its children is sticky. + * +diff --git a/src/x.c b/src/x.c +index 48105b03b1..a3a6aec516 100644 +--- a/src/x.c ++++ b/src/x.c +@@ -41,6 +41,8 @@ typedef struct con_state { + bool unmap_now; + bool child_mapped; + bool is_hidden; ++ bool is_maximized_vert; ++ bool is_maximized_horz; + + /* The con for which this state is. */ + Con *con; +@@ -816,6 +818,44 @@ static void set_hidden_state(Con *con) { + state->is_hidden = should_be_hidden; + } + ++/* ++ * Sets or removes _NET_WM_STATE_MAXIMIZE_{HORZ, VERT} on con ++ * ++ */ ++static void set_maximized_state(Con *con) { ++ if (!con->window) { ++ return; ++ } ++ ++ con_state *state = state_for_frame(con->frame.id); ++ ++ const bool con_maximized_horz = con_is_maximized(con, HORIZ); ++ if (con_maximized_horz != state->is_maximized_horz) { ++ DLOG("setting _NET_WM_STATE_MAXIMIZED_HORZ for con %p(%s) to %d\n", con, con->name, con_maximized_horz); ++ ++ if (con_maximized_horz) { ++ xcb_add_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_MAXIMIZED_HORZ); ++ } else { ++ xcb_remove_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_MAXIMIZED_HORZ); ++ } ++ ++ state->is_maximized_horz = con_maximized_horz; ++ } ++ ++ const bool con_maximized_vert = con_is_maximized(con, VERT); ++ if (con_maximized_vert != state->is_maximized_vert) { ++ DLOG("setting _NET_WM_STATE_MAXIMIZED_VERT for con %p(%s) to %d\n", con, con->name, con_maximized_vert); ++ ++ if (con_maximized_vert) { ++ xcb_add_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_MAXIMIZED_VERT); ++ } else { ++ xcb_remove_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_MAXIMIZED_VERT); ++ } ++ ++ state->is_maximized_vert = con_maximized_vert; ++ } ++} ++ + /* + * Set the container frame shape as the union of the window shape and the + * shape of the frame borders. +@@ -1121,6 +1161,7 @@ void x_push_node(Con *con) { + } + + set_hidden_state(con); ++ set_maximized_state(con); + + /* Handle all children and floating windows of this node. We recurse + * in focus order to display the focused client in a stack first when +diff --git a/testcases/lib/i3test.pm.in b/testcases/lib/i3test.pm.in +index 6d73afca7a..44d4a3d41b 100644 +--- a/testcases/lib/i3test.pm.in ++++ b/testcases/lib/i3test.pm.in +@@ -53,7 +53,7 @@ our @EXPORT = qw( + kill_all_windows + events_for + listen_for_binding +- is_net_wm_state_focused ++ net_wm_state_contains + cmp_tree + ); + +@@ -1090,18 +1090,19 @@ sub listen_for_binding { + return $command; + } + +-=head2 is_net_wm_state_focused ++=head2 net_wm_state_contains + +-Returns true if the given window has the _NET_WM_STATE_FOCUSED atom. ++Returns true if the given window has the given _NET_WM_STATE atom. + +- ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set'); ++ ok(net_wm_state_contains($window, '_NET_WM_STATE_FOCUSED'), ++ '_NET_WM_STATE_FOCUSED set'); + + =cut +-sub is_net_wm_state_focused { +- my ($window) = @_; ++sub net_wm_state_contains { ++ my ($window, $atom_name) = @_; + + sync_with_i3; +- my $atom = $x->atom(name => '_NET_WM_STATE_FOCUSED'); ++ my $atom = $x->atom(name => $atom_name); + my $cookie = $x->get_property( + 0, + $window->{id}, +diff --git a/testcases/t/158-wm_take_focus.t b/testcases/t/158-wm_take_focus.t +index e9a32cd00a..c779365b3e 100644 +--- a/testcases/t/158-wm_take_focus.t ++++ b/testcases/t/158-wm_take_focus.t +@@ -55,8 +55,7 @@ subtest 'Window without WM_TAKE_FOCUS', sub { + my $window = open_window; + + ok(!recv_take_focus($window), 'did not receive ClientMessage'); +- ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set'); +- ++ ok(net_wm_state_contains($window, '_NET_WM_STATE_FOCUSED'), '_NET_WM_STATE_FOCUSED set'); + my ($nodes) = get_ws_content($ws); + my $con = shift @$nodes; + ok($con->{focused}, 'con is focused'); +@@ -92,7 +91,7 @@ subtest 'Window with WM_TAKE_FOCUS and without InputHint', sub { + $window->map; + + ok(!recv_take_focus($window), 'did not receive ClientMessage'); +- ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set'); ++ ok(net_wm_state_contains($window, '_NET_WM_STATE_FOCUSED'), '_NET_WM_STATE_FOCUSED set'); + + my ($nodes) = get_ws_content($ws); + my $con = shift @$nodes; +@@ -114,7 +113,7 @@ subtest 'Window with WM_TAKE_FOCUS and unspecified InputHint', sub { + my $window = open_window({ protocols => [ $take_focus ] }); + + ok(!recv_take_focus($window), 'did not receive ClientMessage'); +- ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set'); ++ ok(net_wm_state_contains($window, '_NET_WM_STATE_FOCUSED'), '_NET_WM_STATE_FOCUSED set'); + + my ($nodes) = get_ws_content($ws); + my $con = shift @$nodes; +diff --git a/testcases/t/283-net-wm-state-hidden.t b/testcases/t/283-net-wm-state-hidden.t +index d6c7b2f8b7..0738ee0b99 100644 +--- a/testcases/t/283-net-wm-state-hidden.t ++++ b/testcases/t/283-net-wm-state-hidden.t +@@ -20,29 +20,8 @@ use i3test; + use X11::XCB qw(:all); + + sub is_hidden { +- sync_with_i3; +- my $atom = $x->atom(name => '_NET_WM_STATE_HIDDEN'); +- + my ($con) = @_; +- my $cookie = $x->get_property( +- 0, +- $con->{id}, +- $x->atom(name => '_NET_WM_STATE')->id, +- GET_PROPERTY_TYPE_ANY, +- 0, +- 4096 +- ); +- +- my $reply = $x->get_property_reply($cookie->{sequence}); +- my $len = $reply->{length}; +- return 0 if $len == 0; +- +- my @atoms = unpack("L$len", $reply->{value}); +- for (my $i = 0; $i < $len; $i++) { +- return 1 if $atoms[$i] == $atom->id; +- } +- +- return 0; ++ return net_wm_state_contains($con, '_NET_WM_STATE_HIDDEN'); + } + + my ($tabA, $tabB, $tabC, $subtabA, $subtabB, $windowA, $windowB); +diff --git a/testcases/t/295-net-wm-state-focused.t b/testcases/t/295-net-wm-state-focused.t +index 68283e9c86..1a9b065eeb 100644 +--- a/testcases/t/295-net-wm-state-focused.t ++++ b/testcases/t/295-net-wm-state-focused.t +@@ -23,17 +23,22 @@ my ($windowA, $windowB); + + fresh_workspace; + $windowA = open_window; +-ok(is_net_wm_state_focused($windowA), 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set'); ++ok(net_wm_state_contains($windowA, '_NET_WM_STATE_FOCUSED'), ++ 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set'); + + $windowB = open_window; +-ok(!is_net_wm_state_focused($windowA), 'when a another window is focused, the old window should not have _NET_WM_STATE_FOCUSED set'); +-ok(is_net_wm_state_focused($windowB), 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set'); ++ok(!net_wm_state_contains($windowA, '_NET_WM_STATE_FOCUSED'), ++ 'when a another window is focused, the old window should not have _NET_WM_STATE_FOCUSED set'); ++ok(net_wm_state_contains($windowB, '_NET_WM_STATE_FOCUSED'), ++ 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set'); + + # See issue #3495. + cmd 'kill'; +-ok(is_net_wm_state_focused($windowA), 'when the second window is closed, the first window should have _NET_WM_STATE_FOCUSED set'); ++ok(net_wm_state_contains($windowA, '_NET_WM_STATE_FOCUSED'), ++ 'when the second window is closed, the first window should have _NET_WM_STATE_FOCUSED set'); + + fresh_workspace; +-ok(!is_net_wm_state_focused($windowA), 'when focus moves to the ewmh support window, no window should have _NET_WM_STATE_FOCUSED set'); ++ok(!net_wm_state_contains($windowA, '_NET_WM_STATE_FOCUSED'), ++ 'when focus moves to the ewmh support window, no window should have _NET_WM_STATE_FOCUSED set'); + + done_testing; +diff --git a/testcases/t/551-net-wm-state-maximized.t b/testcases/t/551-net-wm-state-maximized.t +new file mode 100644 +index 0000000000..4db03ade57 +--- /dev/null ++++ b/testcases/t/551-net-wm-state-maximized.t +@@ -0,0 +1,104 @@ ++#!perl ++# vim:ts=4:sw=4:expandtab ++# ++# Please read the following documents before working on tests: ++# • http://build.i3wm.org/docs/testsuite.html ++# (or docs/testsuite) ++# ++# • http://build.i3wm.org/docs/lib-i3test.html ++# (alternatively: perldoc ./testcases/lib/i3test.pm) ++# ++# • http://build.i3wm.org/docs/ipc.html ++# (or docs/ipc) ++# ++# • https://i3wm.org/downloads/modern_perl_a4.pdf ++# (unless you are already familiar with Perl) ++# ++# Tests for setting and removing the _NET_WM_STATE_MAXIMIZED_VERT and ++# _NET_WM_STATE_MAXIMIZED_HORZ atoms. ++use i3test; ++use X11::XCB qw(:all); ++ ++sub maximized_vert { ++ my ($window) = @_; ++ return net_wm_state_contains($window, '_NET_WM_STATE_MAXIMIZED_VERT'); ++} ++ ++sub maximized_horz { ++ my ($window) = @_; ++ return net_wm_state_contains($window, '_NET_WM_STATE_MAXIMIZED_HORZ'); ++} ++ ++# Returns true if the given window is maximized in both directions. ++sub maximized_both { ++ my ($window) = @_; ++ return maximized_vert($window) && maximized_horz($window); ++} ++ ++# Returns true if the given window is maximized in neither direction. ++sub maximized_neither { ++ my ($window) = @_; ++ return !maximized_vert($window) && !maximized_horz($window); ++} ++ ++my ($winA, $winB, $winC); ++fresh_workspace; ++ ++$winA = open_window; ++ok(maximized_both($winA), 'if there is just one window, it is maximized'); ++ ++cmd 'fullscreen enable'; ++ok(maximized_neither($winA), 'fullscreen windows are not maximized'); ++ ++cmd 'fullscreen disable'; ++ok(maximized_both($winA), 'disabling fullscreen sets maximized to true again'); ++ ++cmd 'floating enable'; ++ok(maximized_neither($winA), 'floating windows are not maximized'); ++ ++cmd 'floating disable'; ++ok(maximized_both($winA), 'disabling floating sets maximized to true again'); ++ ++# Open a second window. ++$winB = open_window; ++ ++# Windows in stacked or tabbed containers are considered maximized. ++cmd 'layout stacking'; ++ok(maximized_both($winA) && maximized_both($winB), ++ 'stacking layout maximizes all windows'); ++ ++cmd 'layout tabbed'; ++ok(maximized_both($winA) && maximized_both($winB), ++ 'tabbed layout maximizes all windows'); ++ ++# Arrange the two windows with a vertical split. ++cmd 'layout splitv'; ++ok(!maximized_vert($winA) && !maximized_vert($winB), ++ 'vertical split means children are not maximized vertically'); ++ok(maximized_horz($winA) && maximized_horz($winB), ++ 'children may still be maximized horizontally in a vertical split'); ++ ++# Arrange the two windows with a horizontal split. ++cmd 'layout splith'; ++ok(maximized_vert($winA) && maximized_vert($winB), ++ 'children may still be maximized vertically in a horizontal split'); ++ok(!maximized_horz($winA) && !maximized_horz($winB), ++ 'horizontal split means children are not maximized horizontally'); ++ ++# Add a vertical split within the horizontal split, and open a third window. ++cmd 'split vertical'; ++$winC = open_window; ++ok(maximized_vert($winA), 'winA still reaches from top to bottom'); ++ok(!maximized_vert($winB) && !maximized_vert($winC), ++ 'winB and winC are split vertically, so they are not maximized vertically'); ++ok(!maximized_horz($winA) && !maximized_horz($winB) && !maximized_horz($winC), ++ 'horizontal split means children are not maximized horizontally'); ++ ++# Change the vertical split container to a tabbed container. ++cmd 'layout tabbed'; ++ok(maximized_vert($winA) && maximized_vert($winB) && maximized_vert($winC), ++ 'all windows now reach from top to bottom'); ++ok(!maximized_horz($winA) && !maximized_horz($winB) && !maximized_horz($winC), ++ 'horizontal split means children are not maximized horizontally'); ++ ++done_testing; diff --git a/i3/f8befe378ab3c9f8d035657ca0247c9b8c242b6b.patch b/i3/f8befe378ab3c9f8d035657ca0247c9b8c242b6b.patch new file mode 100644 index 0000000..8a6f25e --- /dev/null +++ b/i3/f8befe378ab3c9f8d035657ca0247c9b8c242b6b.patch @@ -0,0 +1,146 @@ +From f8befe378ab3c9f8d035657ca0247c9b8c242b6b Mon Sep 17 00:00:00 2001 +From: Orestis Floros +Date: Wed, 31 Jan 2024 08:14:32 +0100 +Subject: [PATCH] Avoid creating redundant containers when switching between + tabbed/stacked and split layouts (#5469) + +Fixes #3001 +--- + release-notes/changes/3-redundant-containers | 1 + + src/con.c | 25 ++++++ + testcases/t/550-split-redundant-containers.t | 82 ++++++++++++++++++++ + 3 files changed, 108 insertions(+) + create mode 100644 release-notes/changes/3-redundant-containers + create mode 100644 testcases/t/550-split-redundant-containers.t + +diff --git a/release-notes/changes/3-redundant-containers b/release-notes/changes/3-redundant-containers +new file mode 100644 +index 000000000..cd6ab9f3d +--- /dev/null ++++ b/release-notes/changes/3-redundant-containers +@@ -0,0 +1 @@ ++avoid creating redundant containers when switching between tabbed/stacked and split layouts +diff --git a/src/con.c b/src/con.c +index aebc46cf8..917e797a6 100644 +--- a/src/con.c ++++ b/src/con.c +@@ -2063,6 +2063,31 @@ void con_set_layout(Con *con, layout_t layout) { + } + } + ++ if (con->type != CT_WORKSPACE && con->parent->type != CT_WORKSPACE && ++ con_num_children(con) == 1 && con_num_children(con->parent) == 1) { ++ /* Special case: Avoid creating redundant containers (#3001): ++ * split h / v (tree_split()) will avoid creating new containers when ++ * the target container is already a single child in L_SPLITH / ++ * L_SPLITV. However, if the layout is tabbed / stacked, a new split is ++ * created. This means, however, that when the user continuously ++ * switches between split h/v and tabbed / stacked, an endless series ++ * of 1-child containers will be created. Since a single level of split ++ * containers on top of tabbed / stacked containers are useful, we want ++ * to avoid this situation here. ++ * Example of past behaviour: S[V[w]] -> S[S[w]] -> S[S[V[w]]] -> … ++ * Example of desired behaviour: S[V[w]] -> S[w] -> S[v[w]] -> … ++ * Therefore, when both the current & parent containers have a single ++ * child, we just close the redundant middle container and proceed with ++ * the parent. */ ++ Con *parent = con->parent; ++ Con *child = TAILQ_FIRST(&(con->nodes_head)); ++ con_detach(child); ++ con_attach(child, parent, true); ++ parent->last_split_layout = con->last_split_layout; ++ tree_close_internal(con, DONT_KILL_WINDOW, true); ++ con = parent; ++ } ++ + if (layout == L_DEFAULT) { + /* Special case: the layout formerly known as "default" (in combination + * with an orientation). Since we switched to splith/splitv layouts, +diff --git a/testcases/t/550-split-redundant-containers.t b/testcases/t/550-split-redundant-containers.t +new file mode 100644 +index 000000000..3dfef3995 +--- /dev/null ++++ b/testcases/t/550-split-redundant-containers.t +@@ -0,0 +1,82 @@ ++#!perl ++# vim:ts=4:sw=4:expandtab ++# ++# Please read the following documents before working on tests: ++# • https://build.i3wm.org/docs/testsuite.html ++# (or docs/testsuite) ++# ++# • https://build.i3wm.org/docs/lib-i3test.html ++# (alternatively: perldoc ./testcases/lib/i3test.pm) ++# ++# • https://build.i3wm.org/docs/ipc.html ++# (or docs/ipc) ++# ++# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf ++# (unless you are already familiar with Perl) ++# ++# Test that splitting and stacked/tabbed layouts do not create redundant ++# containers. ++# Ticket: #3001 ++# Bug still in: 4.22-24-ga5da4d54 ++use i3test; ++ ++cmp_tree( ++ msg => 'toggling between split h/v', ++ layout_before => 'H[a*]', ++ layout_after => 'V[a*]', ++ cb => sub { ++ cmd 'split v, split h, split v'; ++ }); ++cmp_tree( ++ msg => 'toggling between tabbed/stacked', ++ layout_before => 'H[a*]', ++ layout_after => 'S[a*]', ++ cb => sub { ++ cmd 'layout tabbed, layout stacked'; ++ }); ++cmp_tree( ++ msg => 'split h to v and then tabbed', ++ layout_before => 'H[a*]', ++ layout_after => 'T[a*]', ++ cb => sub { ++ cmd 'split v, layout tabbed'; ++ }); ++cmp_tree( ++ msg => 'repeat tabbed layout', ++ layout_before => 'H[a*]', ++ layout_after => 'T[a*]', ++ cb => sub { ++ cmd 'layout tabbed' for 1..5; ++ }); ++cmp_tree( ++ msg => 'split v inside tabbed', ++ layout_before => 'H[a*]', ++ layout_after => 'T[V[a*]]', ++ cb => sub { ++ cmd 'layout tabbed, split v'; ++ }); ++cmp_tree( ++ msg => 'split v inside tabbed and back to just tabbed', ++ layout_before => 'H[a*]', ++ layout_after => 'T[a*]', ++ cb => sub { ++ cmd 'layout tabbed, split v, layout tabbed'; ++ }); ++cmp_tree( ++ msg => 'toggle split v inside tabbed', ++ layout_before => 'H[a*]', ++ layout_after => 'T[V[a*]]', ++ cb => sub { ++ cmd 'layout tabbed, split v, layout tabbed, split v'; ++ }); ++cmp_tree( ++ msg => 'tabbed with 2 nodes inside other tabbed', ++ layout_before => 'T[a*]', ++ layout_after => 'T[T[a b*]]', ++ cb => sub { ++ cmd 'split v'; ++ open_window(wm_class => "b", name => "b"); ++ cmd 'layout tabbed'; ++ }); ++ ++done_testing; diff --git a/i3/i3.SlackBuild b/i3/i3.SlackBuild index 7dbc057..ccefd9a 100755 --- a/i3/i3.SlackBuild +++ b/i3/i3.SlackBuild @@ -29,7 +29,7 @@ PRGNAM=i3 VERSION=${VERSION:-4.23} -BUILD=${BUILD:-1} +BUILD=${BUILD:-2} TAG=${TAG:-_EXs} if [ -z "$ARCH" ]; then @@ -70,16 +70,18 @@ cd $PRGNAM-$VERSION chown -R root:root . find -L . \ \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \ - -o -perm 511 \) -exec chmod 755 {} \; -o \ + -o -perm 511 \) -exec chmod 755 {} \+ -o \ \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \ - -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \; + -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \+ + +patch -p1 -i $CWD/f8befe378ab3c9f8d035657ca0247c9b8c242b6b.patch +patch -p1 -i $CWD/b660d6a902cf44be22c434101dd2a4e6743e26bc.patch # Configure, build, and install: export CFLAGS="-g3 $SLKCFLAGS -flto -rdynamic" export CXXFLAGS="-g3 $SLKCFLAGS -flto -rdynamic" export LDFLAGS="-flto -rdynamic -Wl,--export-dynamic -Wl,-E -Wl,--no-as-needed -Wl,-O2" mkdir meson-build -cd meson-build meson setup \ --prefix=/usr \ --libdir=lib${LIBDIRSUFFIX} \ @@ -93,10 +95,10 @@ meson setup \ --localstatedir=/var \ --buildtype=release \ -Dmans=true \ - .. || exit 1 - "${NINJA:=ninja}" $NUMJOBS || exit 1 - DESTDIR=$PKG $NINJA install || exit 1 -cd .. + meson-build + +meson compile -C meson-build +DESTDIR=$PKG meson install -C meson-build find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \ | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true @@ -147,12 +149,12 @@ for i in $( find $PKG/usr/man -type l ) ; do ln -s $( readlink $i ).gz $i.gz ; r find $PKG -depth -type d -empty -delete || true -cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild +install -Dpm 0644 $CWD/$PRGNAM.SlackBuild $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild mkdir -p $PKG/install -cat $CWD/slack-desc > $PKG/install/slack-desc -cat $CWD/doinst.sh > $PKG/install/doinst.sh -cat $CWD/slack-required > $PKG/install/slack-required +install -Dpm 0644 $CWD/slack-desc $PKG/install/slack-desc +install -Dpm 0644 $CWD/doinst.sh $PKG/install/doinst.sh +install -Dpm 0644 $CWD/slack-required $PKG/install/slack-required cd $PKG /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}