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)
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.
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.
So you end up with both windows selected when doing `focus parent; focus right`?
Yes. And after I can't do "focus left" or anything only with mouse.
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.