Sway has many commands for switching the active workspace and focused window. However, I find that most of my window switching comes down to a few simple commands that focus a specific application, or open it first when it has no open windows yet. E.g.:
$mod+s
: open and/or focus slack$mod+i
: open and/or focus signal$mod+m
: open and/or focus emacs$mod+c
: open and/or focus chromium
In addition to this, some apps like emacs have a separate $mod+Shift+m
command that always opens a new window/instance.
The configuration for this is the following:
# Each app has its own dedicated workspace
assign [app_id="Slack"] 9
assign [app_id="Signal"] 10
# Bind commands to quickly switch to the app
bindsym $mod+s exec ~/bin/launch/slack
bindsym $mod+i exec ~/bin/launch/signal
# Exec the app on startup
exec slack
exec signal-desktop
Then, for each of these applications, there is a script that tries to focus the application. If the application is not running yet it is started, and if it is running in the background only, a new window is opened.
#!/bin/bash
# ~/bin/launch/slack
BINARY='slack'
FOCUS='[app_id="Slack"]'
focus() {
swaymsg "$FOCUS focus" >/dev/null
}
open_or_run() {
if pgrep -fa "/usr/.*/$BINARY" >/dev/null; then
# When the application is already running in the background, starting it
# again will typically open the window and exit.
$BINARY
else
# If the application is not running, start it but do not wait for it.
$BINARY >/dev/null 2>/dev/null &
fi
}
focus_wait() {
# For applications that are slow to start, we try every 0.1s until their
# window is open.
for i in {1..30}; do
if focus; then
break
fi
sleep 0.1
done
}
focus || (
open_or_run
focus_wait
)
For Signal, the script is the same but with variables
BINARY='signal-desktop'
FOCUS='[app_id="Signal"]'
This can also be extended to focus one specific instance of an
application by filtering on title
as well as app_id
.
Back and forth
In addition to the above, it can be nice to quickly switch to the previously active workspace or window.
For workspaces, Sway has the command
workspace back_and_forth
which can be bound to any shortcut.
For switching to previously active windows, I’m using
i3-focus-last
(AUR
package), a window switcher using Rofi that also works with Sway. This
needs exec_always i3-focus-last server
in your Sway config. When
invoked as i3-focus-last menu
, it opens a rofi menu listing all
windows, sorted by most recently focused first.

Figure 1: Window switching with rofi.
Previous browser tab using Vimium
With Vimium, you can also switch back to the most recently active tab,
by doing map <key> visitPreviousTab
. You can find some more of my
Vimium config
here.