Suppose I have window w1, w2 open, and sub-window w1-a, w1-b with w1 as their parent window. Is there a way to move w1-a up to its parent window level?
3 Answers
I found the answer by watch the video tutorial on i3 website:
Shift+$mod+Up
Focus parent:
$mod+a
I hope this might be useful for other people who is also new to the i3wm.
-
4Downvote - answer describes a specific i3 configuration but doesn't include the configuration text.– WinnyNov 25, 2018 at 16:45
I'd like to expand on the author's answer.
Shift+$mod+Up
(move up
for w1-a
) is very dependent what your current layout is.
Let's say the initial state of the container tree is:
.
├── w1
│ ├── w1-a
│ └── w1-b
└── w2
(Note here that w1 is not directly visible - only its two children containers / windows are.)
However while this specifies an ordering of the children of any given parent, it doesn't specify whether each container uses a horizontal or vertical split, and that will affect the outcome of the move up
operation.
Reordering within the same level in the container tree
For example if you use it with w1-b
physically below w1-a
in a vertical split:
. (horizontal split)
├── w1 (vertical split)
│ ├── w1-a
│ └── w1-b
└── w2
then it will just switch them around moving w1-b
above w1-a
and not to the parent top-level.
The container tree now looks like this:
. (horizontal split)
├── w1 (vertical split)
│ └── w1-b
│ ├── w1-a
└── w2
Visually, the change will look like this:
+------------------------------------------+ +------------------------------------------+
| +-----------------+ +-----------------+ | | +-----------------+ +-----------------+ |
| | w1 | | w2 | | | | w1 | | w2 | |
| | +-------------+ | | | | | | +-------------+ | | | |
| | | w1-a | | | | | | | | w1-b | | | | |
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | +-------------+ | | | | | | +-------------+ | | | |
| | +-------------+ | | | | ---> | | +-------------+ | | | |
| | | w1-b | | | | | | | | w1-a | | | | |
| | | (move up) | | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | +-------------+ | | | | | | +-------------+ | | | |
| +-----------------+ +-----------------+ | | +-----------------+ +-----------------+ |
+------------------------------------------+ +------------------------------------------+
Moving one level higher (probably what the questioner intended)
If on the other hand w1-a
is to the left of w1-b
and w2
above w1
:
. (vertical split)
├── w1 (horizontal split)
│ ├── w1-a
│ └── w1-b
└── w2
then after executing move up
on w1-b
, you will end up with w2
and w1-b
on the same (top) level of the tree, but w1-a
will still be in w1
which can be quite confusing, especially given that w1
itself is just an invisible container.
The container tree will now look like this:
.
├── w1-b
├── w1
│ └── w1-a
└── w2
+------------------------------------------+ +------------------------------------------+
| +--------------------------------------+ | | +--------------------------------------+ |
| | w1 | | | | w1-b | |
| | +---------------+ +---------------+ | | | | | |
| | | w1-a | | w1-b | | | | +--------------------------------------+ |
| | | | | (move up) | | | | +--------------------------------------+ |
| | | | | | | | | | w1 | |
| | | | | | | | | | +----------------------------------+ | |
| | +---------------+ +---------------+ | | | | | w1-a | | |
| +--------------------------------------+ | | | | | | |
| +--------------------------------------+ | ---> | | +----------------------------------+ | |
| | w2 | | | +--------------------------------------+ |
| | | | | +--------------------------------------+ |
| | | | | | w2 | |
| | | | | | | |
| | | | | | | |
| +--------------------------------------+ | | +--------------------------------------+ |
+------------------------------------------+ +------------------------------------------+
If you were then to try to move w1-a
up, no visual change would be apparent, but the tree would change and w1
no longer exists:
.
├── w1-b
├── w1-a
└── w2
+------------------------------------------+ +------------------------------------------+
| +--------------------------------------+ | | +--------------------------------------+ |
| | w1-b | | | | w1-b | |
| | | | | | | |
| +--------------------------------------+ | | +--------------------------------------+ |
| +--------------------------------------+ | | +--------------------------------------+ |
| | w1 | | | | w1-a | |
| | +----------------------------------+ | | | | | |
| | | w1-a | | | | | | |
| | | | | | | | | |
| | +----------------------------------+ | | ---> | | | |
| +--------------------------------------+ | | +--------------------------------------+ |
| +--------------------------------------+ | | +--------------------------------------+ |
| | w2 | | | | w2 | |
| | | | | | | |
| | | | | | | |
| +--------------------------------------+ | | +--------------------------------------+ |
+------------------------------------------+ +------------------------------------------+
So you'd need to move it up once more to reorder at the top level and place w1-a
above w1-b
.
Moving two levels higher
If w1-a
is physically above w1-b
in a vertical split, and w2
is to the right of w1
in a horizontal split:
. (horizontal split)
├── w1 (vertical split)
│ ├── w1-a
│ └── w1-b
└── w2
then you will end up with w1-a
being in the same container as the container of w1
and w2
.
Container tree:
.
├── w1-a
└── container
├── w1
│ └── w1-b
└── w2
+------------------------------------------+ +------------------------------------------+
| +-----------------+ +-----------------+ | | +--------------------------------------+ |
| | w1 | | w2 | | | | w1-a | |
| | +-------------+ | | | | | | | |
| | | w1-a | | | | | | | | |
| | | (move up) | | | | | | +--------------------------------------+ |
| | | | | | | | | +--------------------------------------+ |
| | | | | | | | | | container (former root) | |
| | | | | | | | | | +---------------+ +----------------+ | |
| | +-------------+ | | | | | | | w1 | | w2 | | |
| | +-------------+ | | | | ---> | | | +-----------+ | | | | |
| | | w1-b | | | | | | | | | w1-b | | | | | |
| | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | |
| | | | | | | | | | | +-----------+ | | | | |
| | +-------------+ | | | | | | +---------------+ +----------------+ | |
| +-----------------+ +-----------------+ | | +--------------------------------------+ |
+------------------------------------------+ +------------------------------------------+
Conclusion
Moving containers/windows around in i3 can be a bit unintuitive at first but if you understand which container holds which one and where they are positioned you can predict how moving a container will behave. Bear in mind that a move operation may not always result in visible changes.
PS: Little thought experiment: If you move left
w1-a
in the "Reordering within the same level in the container tree" example, you get something similar to the "Moving one level higher" scenario.
-
I appreciate the effort but I find this answer extremely confusing. AFAICS your depictions of the container trees are at least partially ignoring ordering. In the first example, if w1-a is below w1-b, why are you depicting w1-a as earlier in the tree? "Unchanged container tree (besides the position data)" ignores the ordering. Also why call a split container "w1" in one scenario, and "container" in another? Jan 18, 2020 at 10:18
-
@adam-spiers Thanks for the feedbeck. I updated the post with some ascii art to hopefully make it a bit clearer– SyphdiasFeb 3, 2020 at 23:37
-
Thanks a lot, this is a lot clearer! But your tree depictions are still partially ignoring ordering, and I can't see any good reason for that, so I'll fix them. Feb 5, 2020 at 12:10
-
Now fixed to be crystal clear with respect to ordering and positioning. Feb 5, 2020 at 14:40
-
My answer to this problem is having an i3helper bash script which can do this independently of layout via focus parent
and marks. The one extracted command is:
#!/bin/bash
case $1 in
moveToParent)
i3 mark i3ha
i3 focus parent
i3 focus parent
i3 mark i3hb
i3 [con_mark="i3ha"] focus
i3 move window to mark i3hb
i3 unmark i3ha
i3 unmark i3hb
;;
esac
and having it bound in i3 as:
# focus the parent container
bindsym $mod+a focus parent
bindsym $mod+shift+a exec i3helper moveToParent
bindsym $mod+z focus child
It might also be possible to bind the sequence directly, but this suits me better since I do nontrivial preprocessing of other commands too.