26

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?

1
  • 1
    I'm starting to think containers are almost a un-feature. When you have 10 virtual desktops and windows spontaneously zap themselves to the appropriate work space, is it really necessary to have windows placed into a tree structure? Nov 24, 2018 at 23:37

3 Answers 3

27

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.

1
  • 4
    Downvote - answer describes a specific i3 configuration but doesn't include the configuration text.
    – Winny
    Nov 25, 2018 at 16:45
7

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.

5
  • 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
    – Syphdias
    Feb 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
  • Thanks for the fix!
    – Syphdias
    Feb 8, 2020 at 10:40
3

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .