-
Notifications
You must be signed in to change notification settings - Fork 114
Description
So let's say we have a window, for example:
window = i3.get_tree().find_focused()
Now I'd like to know the .right and .left items relative to our window (if those windows exist anyway).
Meaning the windows where user would end up when invoking i3-msg focus right or i3-msg focus left
I'm sure there must be some way to deduce the .right and .left items, but it's beyond my limited imagination.
Why?
If you are familiar with the examples/focus-next-visible.py, I'm kind of trying to create a focus-right/left-visible.py.
I want to be able to navigate through tabbed containers without switching the visible tab, using the i3 movement keys. I have separate keybind for cycling through the tabs. I really love it like this.
Here you can see hacky interpretation of how I like it. It gets around the issue by simply trying out and navigating back when it opens a tab that was not visible to user. It's slow as pope and flickers like damn.
# i3mover.py --- usage example:
# bindsym $mod+l exec --no-startup-id python /path/to/file/i3mover.py right
# bindsym $mod+h exec --no-startup-id python /path/to/file/i3mover.py left
import sys
from i3ipc import Connection
i3 = Connection()
if sys.argv[1] == "right":
dir = "right"
adir = "left"
elif sys.argv[1] == "left":
dir = "left"
adir = "right"
else:
exit()
def find_hidden_windows(tree):
from subprocess import check_output
windows = filter(lambda x: x.window, tree)
hidden_windows = []
for w in windows:
xprop = check_output(['xprop', '-id', str(w.window)]).decode()
if '_NET_WM_STATE_HIDDEN' in xprop:
hidden_windows.append(w.id)
return hidden_windows
tree = i3.get_tree()
origin = tree.find_focused()
hidden_window_ids = find_hidden_windows(tree)
# do the initial move
i3.command(f'focus {dir}')
# check if the initial move got us to hidden window
if i3.get_tree().find_focused().id in hidden_window_ids:
# find the parent tabbed container where we can perform the right/left move
candidate = origin.parent
while True:
if candidate.layout == "tabbed":
break
candidate = candidate.parent
# move back, focus the whole tab container and redo the initial move
i3.command(f'[con_id="{origin.id}"] focus, [con_id="{candidate.id}"] focus, focus {dir}')