swaywm / sway

i3-compatible Wayland compositor
https://swaywm.org
MIT License
14.58k stars 1.11k forks source link

How to set layout of a container on startup? #5070

Open robertjk opened 4 years ago

robertjk commented 4 years ago

Problem

On startup I want to start 2 terminal windows on the same workspace. One of them will run Neovim, and the second one will be an empty (non running any app) terminal. 2 terminals should be displayed in tabbed layout, but the empty terminal should have stacking layout set, so that when I open a new terminal from it, it'll display as a new stack entry in the second tab. Visually:

On startup

-------------------------------------------------------------------------------
|      Tab: Terminal with Neovim       |         Tab: Other terminals         |
-------------------------------------------------------------------------------
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|                                 Terminal 1                                  |
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
-------------------------------------------------------------------------------

After opening a new terminal on other terminal tabs

-------------------------------------------------------------------------------
|      Tab: Terminal with Neovim       |         Tab: Other terminals         |
-------------------------------------------------------------------------------
|      Other terminals tab: Stack entry: Terminal 1                           |
-------------------------------------------------------------------------------
|      Other terminals tab: Stack entry: Terminal 2                           |
-------------------------------------------------------------------------------
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
|                                 Terminal 2                                  |
|                                                                             |
|                                                                             |
|                                                                             |
|                                                                             |
-------------------------------------------------------------------------------

Question

How can I configure such layout on startup in Sway? I tried adding the following to the config file, but it doesn't work. Both terminal windows are displayed, but their layouts are not set properly.

exec swaymsg "workspace $workspace_programming; exec $term --command nvim; layout tabbed; exec $term; split vertical; layout stacking"

Extra question: How can I change the displayed titles of already opened window/containers?

That's probably pretty basic question, but I wasn't able to find that information by myself.

robertjk commented 4 years ago

I managed to do it using that configuration:

exec \
    swaymsg "workspace $workspace_programming"; \
    swaymsg "exec $neovim"; \
    swaymsg "layout tabbed"; \
    sleep 0.3s; \
    swaymsg "exec $term"; \
    sleep 0.3s; \
    swaymsg "split vertical"; \
    swaymsg "layout stacking"

EDIT: The above worked, but only when executed after the startup (using exec_always). For some reason when executed during the startup using exec it doesn't work. Surprisingly for me it doesn't open any window at all, not even Neovim terminal. I refactored it a little bit and this version works during the startup too:

exec swaymsg "workspace $workspace_programming; exec $neovim; layout tabbed;"
exec sleep 0.3s && swaymsg "exec $term";
exec sleep 0.6s && swaymsg "workspace $workspace_programming; split vertical; layout stacking"

I don't understand what's the difference between both versions and why the first doesn't work. If somone can explaind me, I'd be glad.

I also still wonder if there is a cleaner way to do it, without having to resort to sleep.

redowk commented 4 years ago

Hi, I had a similar problem of yours. I wanted to bind a key to open a set of stats tools on a specific workspace, perhaps my experience could be of use to yourself or to anybody else.

Here is how I did it:

put this in sway config:

bindsym $mod+F12 exec ~/.config/sway/lauchStats.sh assign [appid="systat*"] workspace $tag10

lauchStats.sh

!/bin/zsh

tag10="10:stats" swaymsg "workspace $tag10; \ exec alacritty --class systat_stui -e s-tui; \ exec alacritty --class systat_iftop -e sudo iftop" sleep 0.5s swaymsg "[app_id=systat_stui] resize set width 440px" conidstui="$(swaymsg -t get_tree | jq '.. | objects | select(.app_id=="systat_stui") | .id')" conidiftop="$(swaymsg -t get_tree | jq '.. | objects | select(.app_id=="systat_iftop") | .id')"

echo $conidstui

echo $conidiftop

swaymsg "[con_id=$conidstui] move left" swaymsg "[con_id=$conidiftop] splitv" swaymsg "[con_id=$conidiftop] focus; exec alacritty --class systat_htop -e htop" sleep 0.3s conidhtop="$(swaymsg -t get_tree | jq '.. | objects | select(.app_id=="systat_htop") | .id')"

echo $conidhtop

swaymsg "[con_id=$conidhtop] splith" swaymsg "[con_id=$conidhtop] focus; exec alacritty --class systat_iotop -e sudo iotop"

EDIT: There are probably better ways of doing this with code, to anyone interested, ddevault's comments here, and this tool are a nice starting point!

jsravn commented 4 years ago

There does seem to be some strange behavior around exec in the sway config. I've struggled to get a startup layout working reliably for a while now. It would be very helpful for the semantics of exec to be better documented.

Based on my observation, it seems that exec in the sway config are executed async - probably done to speed up start up. There also seems to be a bug where assigns don't work reliably for things exec'd in the sway config. However swaymsg commands seem to exec synchronously, so I can reliably start things up using swaymsg to wrap everything I want to start.