TL;DR
Use sway-toolwait to control the layout and workspace of your autostart apps.

Introduction

I used to have the following in ~/.config/sway/config.d/autostart_applications:

swaymsg "workspace number 1"
swaymsg "exec flatpak run --env=OBSIDIAN_USE_WAYLAND=1 md.obsidian.Obsidian"
swaymsg "exec kitty"

swaymsg "workspace number 2"
swaymsg "exec firefox"

swaymsg "workspace number 3"
swaymsg "exec chromium --ozone-platform-hint=auto"
swaymsg "exec kitty"

swaymsg "workspace number 4"
swaymsg "exec vieb --enable-features=UseOzonePlatform --ozone-platform=wayland"
swaymsg "exec kitty"

As you can see, I have 3 Chromium-based app. They take longer to launch than kitty, so kitty is launched before them and it messes up my layout. Somtimes they’d launch even in the wrong workspaces (e.g., sway would have switched to workspace 3 before done starting firefox in workspace 2, so firefox is in workspace 3)

kitty-on-the-right

I want my kitty to be on the right but it’s always on the left.

Every time I log into my desktop, I have to manually re-position them to my desired layout. I looked for solutions for a long time. A simple sleep doesn’t work, because swaymsg is asynchronous. Then I stumpled upon this reddit thread, and boi have we hit the jackpot.

Getting Started

  1. Go to Robert’s dotfiles and give him a star

  2. Make sure i3ipc is installed:

❯ pip3 install i3ipc
  1. Download sway-toolwait and make it executable:
# download the script to `~/.config/sway/scripts/`
curl -o ~/.config/sway/scripts/sway-toolwait https://gitlab.com/wef/dotfiles/-/raw/master/bin/sway-toolwait
# make the script executable
chmod +x ~/.config/sway/scripts/sway-toolwait
  1. Create startups.sh:
touch ~/.config/sway/scripts/startups.sh

I have the following in startups.sh:

#!/bin/bash

swaymsg "workspace number 1"
/home/username/.config/sway/scripts/sway-toolwait --nocheck --waitfor obsidian -- flatpak run --env=OBSIDIAN_USE_WAYLAND=1 md.obsidian.Obsidian
/home/username/.config/sway/scripts/sway-toolwait kitty --waitfor kitty

swaymsg "workspace number 3"
/home/username/.config/sway/scripts/sway-toolwait --nocheck -- chromium --ozone-platform-hint=auto
/home/username/.config/sway/scripts/sway-toolwait kitty --waitfor kitty

swaymsg "workspace number 4"
/home/username/.config/sway/scripts/sway-toolwait --nocheck --waitfor Vieb -- vieb --enable-features=UseOzonePlatform --ozone-platform=wayland
/home/username/.config/sway/scripts/sway-toolwait kitty --waitfor kitty

swaymsg "workspace number 2"
/home/username/.config/sway/scripts/sway-toolwait --nocheck --waitfor firefox firefox

I. Use full path sway-toolwait if you’re encountered the following caveat issue

II. I launched firefox last because it takes the longest to load

III. I use the flag --nocheck or else it’d take too long to launch all app

  1. Put the following line in ~/.config/sway/config.d/autostart_applications:
exec /home/username/.config/sway/scripts/startups.sh
  1. Restart your machine and enjoy!

Caveat: create a startup.sh instead of using autostart_applications inside config.d

I spent hours debugging why Sway wouldn’t recognize sway-toolwait: I had sway-toolwait int my PATH. After restarting my machine, I got the following error:

Error on line 56 (/home/username/.config/sway/config.d/autostart_applications) 'sway-toolwait "firefox": Unknown/invalid command 'sway-toolwait'.

The issue is that I have the following line in ~/.config/sway/config:

include $HOME/.config/sway/config.d/*

All files inside config.d are Sway-specific. I need the line exec /home/username/.config/sway/scripts/startups.sh to point it towards the shellscript, instead of running the shellscript content inside autostart_applications.

Conclusion

Thank you Robert! If you’re interested, check out Robert’s other sway utilities as well.