eliep / i3-layouts Goto Github PK
View Code? Open in Web Editor NEWDynamic layouts for i3wm
License: MIT License
Dynamic layouts for i3wm
License: MIT License
I'd like to have a layout that always tries to keep all the windows equally sized and arranged as a grid.
I use latest i3-layouts with Python 3.7.0 on Ubuntu 20.04
and It is not working at all
For example
i3l vstack 0.6
gives
{"success":true}
and no changes
I also tried execute on start of i3 from config - not working too
Is there any way to debug this situation?
regards
Hello,
i3-layouts
packages its tests info "test" in the Python path.
This can cause unnecessary conflicts with other random Python packages if they make the same mistake
Some relevant links:
Discovered as I was trying to install habanero
: sckott/habanero#109
python-habanero: /usr/lib/python3.10/site-packages/test/__init__.py exists in filesystem (owned by i3-layouts)
python-habanero: /usr/lib/python3.10/site-packages/test/__pycache__/__init__.cpython-310.opt-1.pyc exists in filesystem (owned by i3-layouts)
python-habanero: /usr/lib/python3.10/site-packages/test/__pycache__/__init__.cpython-310.pyc exists in filesystem (owned by i3-layouts)
First, thanks to you for a very powerful tool!
Here is my configuration file.
set $ws1 1
set $ws2 2
set $ws3 3
set $ws4 4
set $ws5 5
set $ws6 6
set $ws7 7
set $ws8 8
set $ws9 9
set $i3l vstack $ws1
set $i3l vstack $ws2
set $i3l vstack $ws3
set $i3l vstack $ws4
set $i3l vstack $ws5
set $i3l vstack $ws6
set $i3l vstack $ws7
set $i3l vstack $ws8
set $i3l vstack $ws9
I do not seem to be able to make my workspace have a vstack layout by doing this
File "/home/adnan/.local/bin/i3-layouts", line 8, in <module>
sys.exit(main())
^^^^^^
File "/home/adnan/.local/pipx/venvs/i3-layouts/lib/python3.11/site-packages/i3l/cli.py", line 5, in main
connect()
File "/home/adnan/.local/pipx/venvs/i3-layouts/lib/python3.11/site-packages/i3l/connect.py", line 26, in connect
workspace_layouts = WorkspaceLayout.load(i3_config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/adnan/.local/pipx/venvs/i3-layouts/lib/python3.11/site-packages/i3l/config.py", line 42, in load
i3l_options = [' '.join([i3_vars[token] if token.startswith('$') else token for token in i3l_option.split(' ')])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/adnan/.local/pipx/venvs/i3-layouts/lib/python3.11/site-packages/i3l/config.py", line 42, in <listcomp>
i3l_options = [' '.join([i3_vars[token] if token.startswith('$') else token for token in i3l_option.split(' ')])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/adnan/.local/pipx/venvs/i3-layouts/lib/python3.11/site-packages/i3l/config.py", line 42, in <listcomp>
i3l_options = [' '.join([i3_vars[token] if token.startswith('$') else token for token in i3l_option.split(' ')])
~~~~~~~^^^^^^^
KeyError: '$ws1'
This is the error i get whenever i run it from terminal
I can't seem to get the keybinds to work for manipulating the layouts. ' i3-layouts ' starts with the i3 config, and commands can be issued via the terminal successfully, I just can't seem to use keybinds calling ' i3l ' functions.
If I manually issue the " i3l [layout] " in the terminal, it does work as expected, same with moving by using " i3l move (left,right) "
I largely copied my config based on the README and simply changed some keys, so I have the following lines:
50 │
51 │ set $i3l spiral to workspace workspace $ws1
52 │ set $i3l hstack 0.6 up to workspace workspace $ws2
53 │ set $i3l spiral 0.6 to workspace workspace $ws3
[snipped for readability]
59 │ # Binds to Change Layouts
60 │
61 │ bindsym $mod+v exec "i3l vstack 0.5 && notify-send \"Layout VStack\""
62 │ bindsym $mod+h exec i3l hstack 0.5 && notify-send "Layout HStack"
63 │ bindsym $mod+s exec i3l spiral && notify-send "Spiral Layout"
64 │ bindsym $mod+q exec i3l 2columns && notify-send "2 Column Layout"
65 │ bindsym $mod+w exec i3l 3columns && notify-send "3 Column Layout"
66 │ bindsym $mod+c exec i3l companion && notify-send "Companion Layout"
67 │ bindsym $mod+a exec i3l autosplit && nofity-send "Automatic Layout"
68 │ bindsym $mod+n exec i3l none && notify-send "i3 Layouts Disabled"
Originally I had the i3-layouts startup set as:
476 | exec_always --no-startup-id sleep 2 && /$HOME/.local/bin/i3-layouts
I did try moving it up in the list as the following:
3 | exec ~/.local/bin/i3-layouts
Sometimes we would like to swap containers. One way to do it is via move left
etc., which are handled by i3-layouts already. Another way is to utilize markers, and via swap container with some-mark
. For me, I customized the following two functionalities:
These functions conflict with i3-layouts, and the layout becomes a complete mess. The reason is simple: these functions are based on swap container with some-mark
, but i3-layouts does not provide a way to also swap those "i3l:*" marks when such a swap occurs.
It would be great if either
swap container with some-mark
, which swaps the container and also their "i3l:*" marks. OrIn case you need it, here is the part of my i3 config that implements the functions above:
bindsym $mod+h mark --add prev-mark; focus left
bindsym $mod+j mark --add prev-mark; focus down
bindsym $mod+k mark --add prev-mark; focus up
bindsym $mod+l mark --add prev-mark; focus right
# swap with the previously focused container
bindsym $mod+i mark --add temp_mark, swap container with mark prev-mark, [con_mark="temp-mark"] mark --replace prev-mark, unmark "temp-mark"
# mark current container for swapping
bindsym $mod+bracketleft mark --add swap-mark
# swap with previously marked container
bindsym $mod+bracketright mark --add swap-orig, swap container with mark swap-mark, unmark "swap-mark", [con_mark="swap-orig"] mark --add swap-mark, unmark "swap-orig"
Is there a way or plans to add support for workspace_layout. I basically want the spiral as the default tiling method for any new workspace.
Great project!
Floating windows are handled weirdly in i3-layouts after we toggle and make it non-floating. Such weird behavior is not immediately observable, but will emerge when layout changes.
For example, I have the following in my i3 config:
set $term terminator
# open terminal
bindsym $mod+Return exec $term
# open a floating terminal
bindsym $mod+Shift+Return exec $term -T floating
# Terminator with title "floating" should be floating
for_window [class="Terminator" title="floating"] floating enable
# toggle tiling / floating
bindsym $mod+Shift+space floating toggle
And I can decide whether to start a terminal in tiling (press $mod+Return
), or in a temporary floating position (press $mod+Shift+Return
). If I later find that I need a floating terminal to become tiling, I can press $mod+Shift+space
to toggle it between floating and tiling. (I am using terminator, but many other terminals also have the ability to set its title when started. For example, if you use alacritty
, you can use -t
instead of -T
to specify its title.)
Here is one way to reproduce the inconstancy I mentioned with my config. In an empty workspace set to autosplit
with set $i3l autosplit to workspace $ws10
, press $mod+Return
twice to create two terminals side by side. Now press $mod+Shift+Return
to open a floating terminal, and press $mod+Shift+space
to toggle it into tiling. The layout looks like the following, where window 3 used to be floating, which is correct.
+----------+----------+
| | 2 |
| 1 +----------+
| | 3 |
+----------+----------+
Now focus on window 2, and delete it. We would expect the layout to be like:
+----------+----------+
| | |
| 1 | 3 |
| | |
+----------+----------+
But in fact, what we are left with is like:
+---------------------+
| +----------+
| 1 | 3 |
| +----------+
+---------------------+
where it seems correct: window 1 and window 3 each covers half of the workspace. However, this is not the truth. Window 1 is actually covering the whole workspace, while window 3 is now a floating window roughly covering the right half. What is worse, we are currently focused on window 3, a floating window. This means all focus movements are not working, until you realize window 3 is a floating window, and make it tiling again.
From my understanding, this comes from the Redraw limitation you mentioned. One solution maybe give a wrapper for command floating toggle
, so we know how to restore.
In addition, since you are using redraw, I would expect that tabbed and stacked layouts came from i3 would also suffer.
It would be nice to have a way to swap with the main window of the current layout.
Currently i'm using a command to parse the current workspace name to swap with the main mark of the current workspace.
Like so: i3l swap container with mark $(i3-current-workspace):main
$ cat .local/bin/i3-current-workspace
i3-msg -t get_workspaces \
| jq '.[] | select(.focused==true).name' \
| cut -d"\"" -f2
Hi there,
Just tried to use i3-layouts for the first time. My i3 is version 4.22 and my i3-layouts is version 0.13.2 installed from the AUR.
I define my workspaces in my i3 config as:
set $ws1 1
set $ws2 2
set $ws3 3
set $ws4 4
set $ws5 5
set $ws6 6
set $ws7 7
set $ws8 8
set $ws9 9
set $ws10 10
and then have my i3-layouts config at the bottom of my i3 config file as:
set $i3l companion 0.3 0.3 alt-down to workspace $ws1
set $i3l 3columns 0.5 0.33 0 right to workspace $ws2
set $i3l 3columns 0.5 0.33 0 right to workspace $ws3
When I start i3, i3-layouts is not loading and everything is just default i3 behaviour. If I run i3-layouts from the CLI I get the following exception:
Traceback (most recent call last):
File "/usr/bin/i3-layouts", line 33, in <module>
sys.exit(load_entry_point('i3-layouts==0.13.2', 'console_scripts', 'i3-layouts')())
File "/usr/lib/python3.10/site-packages/i3l/cli.py", line 5, in main
connect()
File "/usr/lib/python3.10/site-packages/i3l/connect.py", line 26, in connect
workspace_layouts = WorkspaceLayout.load(i3_config)
File "/usr/lib/python3.10/site-packages/i3l/config.py", line 42, in load
i3l_options = [' '.join([i3_vars[token] if token.startswith('$') else token for token in i3l_option.split(' ')])
File "/usr/lib/python3.10/site-packages/i3l/config.py", line 42, in <listcomp>
i3l_options = [' '.join([i3_vars[token] if token.startswith('$') else token for token in i3l_option.split(' ')])
File "/usr/lib/python3.10/site-packages/i3l/config.py", line 42, in <listcomp>
i3l_options = [' '.join([i3_vars[token] if token.startswith('$') else token for token in i3l_option.split(' ')])
KeyError: '$ws1'
I have also tried:
set $i3l companion 0.3 0.3 alt-down to workspace number $ws1
set $i3l 3columns 0.5 0.33 0 right to workspace number $ws2
set $i3l 3columns 0.5 0.33 0 right to workspace number $ws3
I'm not sure what's gone wrong here as this seems to match the readme. Any thoughts would be welcome.
no_focus [class=".*"]
to the i3 config fileWindows should open as dictated by the layout
Focused window will swap with newly opened window, or sometimes incorrectly open floating if working with other floating windows.
Hello,
I've installed i3-layouts via the guide (Ive had this working on another distro easily)
(Currently on gentoo)
Installed via the pip, put the .local/bin in my path Everything looks correct but for some reason i can't get the layouts
Normally the terminals say current or previous but im getting nothing. if i start i3-layouts manually i3-layouts & the current terminal will say current and if i open another terminal it will say current also. but nothing is working. Any ideas?
Going back to xfce for now until this gets resolved. Can't really use i3 anymore. manually tiling is boring and takes to much work
Hi, when I create a terminal in my ws1 and the immediately proceed to create a second one, it is sent to the ws 2, further creation of terminals result in the master window being on ws 1 and the child windows being on ws 2, I would expect them to stay in the same workspace I create them.
After installation via pip i3-layouts command doesn't work. Neither i3l does.
Sending
i3l none
stops i3-layouts managing the workspace.
But there is also an error message from layouts.py “Invalid layout name: none.. Skipping”
Relevant part of the debug log:
[2022-03-12 12:56:10,616] DEBUG {handlers.py:17} - [ipc] tick event - payload:
[2022-03-12 12:56:15,517] DEBUG {handlers.py:17} - [ipc] tick event - payload:i3-layouts none
[2022-03-12 12:56:15,523] ERROR {layouts.py:494} - [layouts] Invalid layout name: none. Skipping
[2022-03-12 12:56:15,523] DEBUG {ticks.py:83} - [ipc] tick event - unset workspace layout
I suppose the problem is at the end of layouts.py (from line 488 onwards):
@classmethod
def create(cls, name: str, params: List[Any], workspace_name: str) -> Optional['Layout']:
try:
layout_name = LayoutName(name)
return cls.factory[layout_name].create(workspace_name, params) if layout_name in cls.factory else None
except ValueError:
logger.error(f'[layouts] Invalid layout name: {name}. Skipping')
return None
layout_name = LayoutName(name)
fails, because none
is not a vaild LayoutName
after following instructions, making sure exec i3-layouts
and set $i3l spiral 0.5 to workspace $ws1
in my i3 config file, it does not work. i still get windows splitting horizontally. I have i3wm and i3-gaps installed.
I just tried i3-layouts with i3gaps and it works as intended. But all the scratchpads I define in the i3 config are shown on startup instead of being hidden.
This issue appeared with the use of i3-layouts, but I'm not sure what the problem is. I have this on my Desktop and on my Laptop.
i use this line
bindsym $mod+v exec i3l autosplit 0
and show this
sometimes windows disappear while the layout gets rearranged after moving windows from or to different workspaces or while restarting i3
vstack
layout specifically)i3l move left
The floating window should be moved to the left by 1 px
The floating window is swapped with the tiling window
Today I got the following error message after python 3.12.3-1 update:
Traceback (most recent call last):
File "/usr/lib/python3.12/importlib/metadata/init.py", line 397, in from_name
return next(cls.discover(name=name))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
StopIteration
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/bin/i3-layouts", line 33, in
sys.exit(load_entry_point('i3-layouts==0.13.2', 'console_scripts', 'i3-layouts')())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/bin/i3-layouts", line 22, in importlib_load_entry_point
for entry_point in distribution(dist_name).entry_points
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/importlib/metadata/init.py", line 862, in distribution
return Distribution.from_name(distribution_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/importlib/metadata/init.py", line 399, in from_name
raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: No package metadata was found for i3-layouts
A few info:
OS: Arch Linux
WM: I3 (original)
I am using the 3 column layout as follows:
set $i3l 3columns 0.5 0.5 1 right to workspace $ws1
set $i3l 3columns 0.5 0.5 1 right to workspace $ws2
set $i3l 3columns 0.5 0.5 1 right to workspace $ws3
set $i3l 3columns 0.5 0.5 1 right to workspace $ws4
set $i3l 3columns 0.5 0.5 1 right to workspace $ws5
set $i3l 3columns 0.5 0.5 1 right to workspace $ws6
set $i3l 3columns 0.5 0.5 1 right to workspace $ws7
set $i3l 3columns 0.5 0.5 1 right to workspace $ws8
However, I have noticed i3-layouts doesn't start with i3 (using exec i3-layouts). I forwarded the output to a text file to see what was up, but all it reads is "list index out of range".
The workaround is to launch with exec_always i3-layouts, and refresh i3 upon startup, but this is sub optimal.
Suppose I have workspace 10 on screen 1 and workspace 9 on screen 2, if I try using a layout on workspace 9, it'll move some or all windows to workspace 10 and break layouts on both workspaces. It is not always, but most of the time it'll happen. Of course, it doesn't matter which are the workspaces, but will always happen with the workspaces being on display in both screens.
Here are the logs when it happened:
[2021-09-12 12:05:46,550] DEBUG {handlers.py:34} - [ipc] workspace focus event - workspace:9, old:10
[2021-09-12 12:05:46,568] DEBUG {handlers.py:48} - [ipc] no workspace layouts exists for 9
[2021-09-12 12:05:46,569] DEBUG {handlers.py:79} - [ipc] window move event - container:94463202295456
[2021-09-12 12:05:46,582] DEBUG {handlers.py:85} - [ipc] window move event - to another workspace
[2021-09-12 12:05:46,583] DEBUG {handlers.py:143} - [ipc] window focus event - container:94463202334752:71303170
[2021-09-12 12:05:46,587] DEBUG {handlers.py:155} - [ipc] window focus event - no workspace layout
[2021-09-12 12:05:46,587] DEBUG {handlers.py:17} - [ipc] tick event - payload:i3-layouts rebuild workspace_focus
[2021-09-12 12:05:49,596] DEBUG {handlers.py:34} - [ipc] workspace focus event - workspace:10, old:9
[2021-09-12 12:05:49,600] DEBUG {handlers.py:37} - [ipc] workspace layouts exists for 10
[2021-09-12 12:05:49,600] DEBUG {state.py:237} - [state] rebuilding for RebuildCause.WORKSPACE_FOCUS
[2021-09-12 12:05:49,617] DEBUG {handlers.py:143} - [ipc] window focus event - container:94463202295456:90177538
[2021-09-12 12:05:49,623] DEBUG {handlers.py:158} - [ipc] window focus event - workspace layout not autosplit
[2021-09-12 12:05:49,623] DEBUG {handlers.py:63} - [ipc] window close event - container:94463202295456
[2021-09-12 12:05:49,626] DEBUG {handlers.py:100} - [ipc] window new event - container:94463202295456:90177538
[2021-09-12 12:05:49,627] DEBUG {handlers.py:113} - [ipc] window new event - update layout
[2021-09-12 12:05:49,636] DEBUG {handlers.py:143} - [ipc] window focus event - container:94463202295456:90177538
[2021-09-12 12:05:49,640] DEBUG {handlers.py:155} - [ipc] window focus event - no workspace layout
[2021-09-12 12:05:49,641] DEBUG {handlers.py:34} - [ipc] workspace focus event - workspace:9, old:10
[2021-09-12 12:05:49,643] DEBUG {handlers.py:48} - [ipc] no workspace layouts exists for 9
[2021-09-12 12:05:49,643] DEBUG {handlers.py:79} - [ipc] window move event - container:94463202295456
[2021-09-12 12:05:49,646] DEBUG {handlers.py:82} - [ipc] window move event - inside workspace
[2021-09-12 12:05:49,647] DEBUG {handlers.py:79} - [ipc] window move event - container:94463202295456
[2021-09-12 12:05:49,649] DEBUG {handlers.py:82} - [ipc] window move event - inside workspace
[2021-09-12 12:05:49,649] DEBUG {handlers.py:17} - [ipc] tick event - payload:i3-layouts rebuild workspace_focus
[2021-09-12 12:05:49,651] DEBUG {handlers.py:17} - [ipc] tick event - payload:i3-layouts rebuild workspace_focus
[2021-09-12 12:05:49,658] DEBUG {handlers.py:34} - [ipc] workspace focus event - workspace:10, old:9
[2021-09-12 12:05:49,660] DEBUG {handlers.py:37} - [ipc] workspace layouts exists for 10
[2021-09-12 12:05:49,661] DEBUG {handlers.py:17} - [ipc] tick event - payload:i3-layouts rebuild workspace_focus
[2021-09-12 12:05:55,609] DEBUG {handlers.py:34} - [ipc] workspace focus event - workspace:9, old:10
[2021-09-12 12:05:55,612] DEBUG {handlers.py:48} - [ipc] no workspace layouts exists for 9
[2021-09-12 12:05:55,612] DEBUG {handlers.py:143} - [ipc] window focus event - container:94463202334752:71303170
[2021-09-12 12:05:55,618] DEBUG {handlers.py:155} - [ipc] window focus event - no workspace layout
[2021-09-12 12:05:55,618] DEBUG {handlers.py:17} - [ipc] tick event - payload:i3-layouts rebuild workspace_focus
[2021-09-12 12:05:55,624] DEBUG {handlers.py:143} - [ipc] window focus event - container:94463202295456:90177538
[2021-09-12 12:05:55,629] DEBUG {handlers.py:155} - [ipc] window focus event - no workspace layout
Also, sometimes when spawning a window on a workspace it'll go straight to other workspace on the other screen and cause this error:
'>=' not supported between instances of 'NoneType' and 'int'
Traceback (most recent call last):
File "/home/misterio/.local/bin/i3-layouts", line 8, in
sys.exit(main())
File "/home/misterio/.local/lib/python3.9/site-packages/i3l/cli.py", line 5, in main
connect()
File "/home/misterio/.local/lib/python3.9/site-packages/i3l/connect.py", line 41, in connect
i3.main()
File "/home/misterio/.local/lib/python3.9/site-packages/i3ipc/connection.py", line 514, in main
raise loop_exception
File "/home/misterio/.local/lib/python3.9/site-packages/i3ipc/connection.py", line 497, in main
while not self._event_socket_poll():
File "/home/misterio/.local/lib/python3.9/site-packages/i3ipc/connection.py", line 477, in _event_socket_poll
raise e
File "/home/misterio/.local/lib/python3.9/site-packages/i3ipc/connection.py", line 474, in _event_socket_poll
self._pubsub.emit(event_name, event)
File "/home/misterio/.local/lib/python3.9/site-packages/i3ipc/_private/pubsub.py", line 28, in emit
s['handler'](self.conn, data)
File "/home/misterio/.local/lib/python3.9/site-packages/i3l/handlers.py", line 42, in _on_workspace_focus
state.start_rebuild(RebuildCause.WORKSPACE_FOCUS, context,
File "/home/misterio/.local/lib/python3.9/site-packages/i3l/state.py", line 238, in start_rebuild
self.rebuild_action.start_rebuild(context, rebuild_cause, main_mark, last_mark, con_id)
File "/home/misterio/.local/lib/python3.9/site-packages/i3l/state.py", line 175, in start_rebuild
self.containers_to_recreate = self._containers_after(con_id, containers, context.workspace_sequence)
File "/home/misterio/.local/lib/python3.9/site-packages/i3l/state.py", line 162, in _containers_after
return [RebuildContainer(con) for con in containers
File "/home/misterio/.local/lib/python3.9/site-packages/i3l/state.py", line 163, in
if con_id == 0 or workspace_sequence.get_order(con.id) >= workspace_sequence.get_order(con_id)]
TypeError: '>=' not supported between instances of 'NoneType' and 'int'
Interesting, the error always happen with primary laptop screen, it doesn't break when using layouts on external monitor.
Thank you for your attention and for i3-layouts, I really like it.
I tried i3-layouts today, and it seems awesome. Before this, I have been a happy user of autotiling, which automatically decide whether to use splith/splitv depending on the dimension of the currently focused window. Is it possible for i3-layouts to add a similar feature? Spiral seems close to what I want, but it always divide the smallest window, instead of the currently focused one.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.