Skip to content

Any way to get element on 'right' or 'left' of a given element? #207

@omenius

Description

@omenius

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}')

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions