The i3 FAQ has migrated to https://github.com/i3/i3/discussions. All content here is read-only.
Ask Your Question
2

Focus between and inside containers

asked 2013-11-03 18:37:44 +0000

uzsolt gravatar image

My question is: how can I do a bindsym to focus between containers and another bindsym inside a container?

An example: I've a container named "A" and two clients inside A: A1 and A2. On same workspace I've an another container named "B" with two clients: B1 and B2. I want a bindsym to change focus in the focused container (A1 and A2 and back to A1, etc.) and another bindsym to change the focused container.

My (first) idea:

force_focus_wrapping true
# change focused container
bindsym $mod+Tab focus parent; focus right
bindsym $mod+Shift+Tab focus parent; focus left
# change focused client in container 
bindsym $winkey+Left focus left
bindsym $winkey+Right focus right

It works well when I've containers. But when I don't have containers the focus parent will fails. Maybe would be nice when the focused "object" is a simple client focus parent sets the focus to the client.

Any idea?

edit retag flag offensive close merge delete

Comments

I'm not sure, what you mean with "don't have containers". Unless there is no window at all on a workspace, there are containers. And there are no windows, where should `focus right` go? With two outputs the combined command seems to work even when starting from an empty workspace.

Adaephon gravatar imageAdaephon ( 2013-11-04 07:48:08 +0000 )edit

Maybe I was equivocal: don't have containers means: I open two seperate windows e.g. a terminal and a browsers and doesn't exist child-parent relationship.

uzsolt gravatar imageuzsolt ( 2013-11-04 09:53:12 +0000 )edit

So you end up with both windows selected when doing `focus parent; focus right`?

Adaephon gravatar imageAdaephon ( 2013-11-04 10:26:17 +0000 )edit

Yes. And after I can't do "focus left" or anything only with mouse.

uzsolt gravatar imageuzsolt ( 2013-11-04 10:40:30 +0000 )edit

FWIW: there is also `focus child` (not bound by default): this would allow to move the focus down again at least (without using the mouse). Also switching workspaces back and forth might help then.

blueyed gravatar imageblueyed ( 2014-02-26 21:04:25 +0000 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2013-11-04 13:02:13 +0000

Adaephon gravatar image

updated 2013-11-05 08:49:03 +0000

Every window in i3 is inside one container or another (the outermost being workspaces). When a window is created on an empty workspace, a new container is opened with the settings of workspace_layout. Each following window is placed in the same container unless another container is explicitly created (by moving a window outside the container or with the split command).

So there is no such thing as a "simple" client as there is no "normal" or "complex" client from which it could be distinguished.

The problems you are experiencing do not result from focus parent but from the focus right portion of your command. After shifting focus to another container, i3 focuses the last active window in this container. In the case you are describing there is no other container, so i3 has nothing new to focus and does just nothing when you say focus right and so the parent container remains focused.

An easy solution for the immediate problem is just adding focus child to each command:

# change focused container
bindsym $mod+Tab focus parent; focus right; focus child
bindsym $mod+Shift+Tab focus parent; focus left; focus child

This way at least the previous window gets refocused when no other container is selected (i.e. the focus seems not to be moved in any way) and you can use the other binding to switch focus. (Strictly speaking, focus child will fail in cases where a new window is already selected, but there are no side effects to trying.)

There is no way to make focus parent; focus right behave like focus right in cases where there is no other container next to the parent container (which is the case you are describing in your comment) by just using i3 configuration.


With the exception of the window criteria (which do not include the windows position), i3 does not provide conditional statements inside its configuration. In order to do what you are looking for you need to access the i3 IPC interface. You can use i3-msg, which comes with i3, or a third-party library. I'll concentrate on i3-msg, some libraries may already have predefined functions for some parts.

With i3-msg you can call any command you may bind to a key in the i3 configuration, e.g. i3-msg focus right. It also returns JSON on every call to tell you if it was successful. (Sadly it does not return exitcodes other than 0 to tell you of failures)

Knowing that a successful shift of focus ends up with a window focused and that windows do not have children this is probably one of the shortest solutions:

#/bin/sh
i3-msg "focus parent; focus ${1}; focus child"
i3-msg "focus child" | grep "true" || i3-msg "focus ${1}"

Save as "superfocus" and set bindsym+Tab exec superfocus right


Another possibility would be parsing the tree in which i3 manages its windows and containers and check actively if there is only one container on the workspace. You can get a list of workspaces with i3-msg ...

(more)
edit flag offensive delete link more

Comments

Oh, understand the logic of behavior :) But it doesn't work when you've two windows on a workspace.

uzsolt gravatar imageuzsolt ( 2013-11-04 13:33:04 +0000 )edit

That's strange. I tested it before posting and while I couldn't change focus with $mod+Tab, at least I didn't end up with both windows (or rather their parent container) selected. Could you bind the single commands to separate keys and see where it stops working as expected?

Adaephon gravatar imageAdaephon ( 2013-11-04 14:30:19 +0000 )edit

Tested. "focus parent" -> works (seems focused full workspace) but "focus left" does nothing. And after "focus child" back to original state.

uzsolt gravatar imageuzsolt ( 2013-11-04 18:37:28 +0000 )edit

Yes, that is what I wrote just after the block of code. What you are looking for will need some scripting/programming, using i3-msg or other i3 IPC library. [http://i3wm.org/docs/ipc.html#_see_also_existing_libraries] I'll add a paragraph that outlines a possible solution.

Adaephon gravatar imageAdaephon ( 2013-11-05 06:09:41 +0000 )edit

Thanks. I'll check this and I want try with some scripting (I've used awesome wm so I've some experience ;) ).

uzsolt gravatar imageuzsolt ( 2013-11-05 07:03:30 +0000 )edit

Almost perfect. It doesn't work when I've two windows, one is a windows and other is a container with two "sub-windows". I'm working on too :) Thanks for idea :)

uzsolt gravatar imageuzsolt ( 2013-11-06 09:36:59 +0000 )edit

Question Tools

Stats

Asked: 2013-11-03 18:37:44 +0000

Seen: 1,571 times

Last updated: Nov 05 '13