ref: d4ae538c007a18559fe58aabf9995d225f801a93 swayr/README.md -rw-r--r-- 8.9 KiB
d4ae538cTassilo Horn Release v0.6.0-beta.1 6 months ago

#Swayr is a window switcher (and more) for sway

builds.sr.ht status latest release License GPL 3 or later

Swayr consists of a demon, and a client. The demon swayrd records window/workspace creations, deletions, and focus changes using sway's JSON IPC interface. The client swayr offers subcommands, see swayr --help, and sends them to the demon which executes them.

Right now, there are these subcommands:

  • next-window focuses the next window in depth-first iteration order of the tree.
  • prev-window focuses the previous window in depth-first iteration order of the tree.
  • switch-window displays all windows in the order urgent first, then last-recently-used, focused last and focuses the selected.
  • quit-window displays all windows and quits the selected one.
  • switch-to-urgent-or-lru-window switches to the next window with urgency hint (if any) or to the last recently used window.
  • switch-workspace displays all workspaces in LRU order and switches to the selected one.
  • switch-workspace-or-window displays all workspaces and their windows and switches to the selected workspace or window.
  • quit-workspace-or-window displays all workspaces and their windows and allows to quit either the selected workspace (all its windows) or the selected window.
  • execute-swaymsg-command displays most swaymsg which don't require additional input and executes the selected one. That's handy especially for less often used commands not bound to a key.
  • execute-swayr-command displays all commands above and executes the selected one. (This is useful for accessing swayr commands which are not bound to a key.)


A screenshot of swayr switch-window

A screenshot of swayrswitch-workspace-or-window


You'll need to install the current stable rust toolchain using the one-liner shown at the official rust installation page.

Then you can install swayr like so:

cargo install swayr

For getting updates easily, I recommend the cargo install-update plugin.

# Install it once.
cargo install install-update

# Then you can update all installed rust binary crates including swayr using:
cargo install-update --all

# If you only want to update swayr, you can do so using:
cargo install-update -- swayr


You need to start the swayr demon swayrd in your sway config (~/.config/sway/config) like so:

exec env RUST_BACKTRACE=1 swayrd > /tmp/swayrd.log 2>&1

The setting of RUST_BACKTRACE=1 and the redirection of the output to some logfile is optional but helps a lot when something doesn't work. Especially, if you encounter a crash in certain situations and you want to report a bug, it would be utmost helpful if you could reproduce the issue with backtrace and logging and attach that to your bug report.

Next to starting the demon, you want to bind swayr commands to some keys like so:

bindsym $mod+Space exec env RUST_BACKTRACE=1 \
    swayr switch-window >> /tmp/swayr.log 2>&1

bindsym $mod+Delete exec env RUST_BACKTRACE=1 \
    swayr quit-window > /tmp/swayr.log 2>&1

bindsym $mod+Tab exec env RUST_BACKTRACE=1 \
    swayr switch-to-urgent-or-lru-window >> /tmp/swayr.log 2>&1

bindsym $mod+Next exec env RUST_BACKTRACE=1 \
    swayr next-window >> /tmp/swayr.log 2>&2

bindsym $mod+Prior exec env RUST_BACKTRACE=1 \
    swayr prev-window >> /tmp/swayr.log 2>&2

bindsym $mod+Shift+Space exec env RUST_BACKTRACE=1 \
    swayr switch-workspace-or-window >> /tmp/swayr.log 2>&1

bindsym $mod+c exec env RUST_BACKTRACE=1 \
    swayr execute-swaymsg-command >> /tmp/swayr.log 2>&1

bindsym $mod+Shift+c exec env RUST_BACKTRACE=1 \
    swayr execute-swayr-command >> /tmp/swayr.log 2>&1

Of course, configure the keys to your liking. Again, enabling rust backtraces and logging are optional.


Swayr can be configured using the ~/.config/swayr/config.toml config file.

If it doesn't exist, a simple default configuration will be created on the first invocation for use with the wofi menu program.

It should be easy to adapt that default config for usage with other menu programs such as dmenu, bemenu, rofi, a script spawning a terminal with fzf, or whatever. The only requirement is that the launcher needs to be able to read the items to choose from from stdin, and spit out the selected item to stdout.

The default config looks like this:

executable = 'wofi'
args = [

window_format = '{urgency_start}<b>“{title}”</b>{urgency_end} — <i>{app_name}</i> on workspace {workspace_name}   <span alpha="20000">({id})</span>'
workspace_format = '<b>Workspace {name}</b>   <span alpha="20000">({id})</span>'
html_escape = true
urgency_start = '<span background="darkred" foreground="yellow">'
urgency_end = '</span>'
icon_dirs = [
fallback_icon = '/usr/share/pixmaps/archlinux-logo.png'

In the [menu] section, you can specify the menu program using the executable name or full path, and the args (flags and options) it should get passed. If some argument contains the placeholder {prompt}, it is replaced with a prompt such as "Switch to window" depending on context.

In the [format] section, format strings are specified defining how selection choises are to be layed out. wofi supports pango markup which makes it possible to style the text using HTML and CSS. The following formats are supported right now.

  • window_format defines how windows are displayed. The placeholder {title} is replaced with the window's title, {app_name} with the application name, {marks} with a comma-separated list of the window's marks, {app_icon} with the application's icon (a path to a PNG or SVG file), {workspace_name} with the name or number of the workspace the window is shown, and {id} is the window's sway-internal con id. There are also the placeholders {urcency_start} and {urgency_end} which get replaced by the empty string if the window has no urgency flag, and with the values of the same-named formats if the window has the urgency flag set. That makes it possible to highlight urgent windows as shown in the default config.
  • workspace_format defines how workspaces are displayed. There are the placeholders {name} which gets replaced by the workspace's number or name, and {id} which gets replaced by the sway-internal con id of the workspace.
  • html_escape defines if the strings replacing the placeholders above (except for {urgency_start} and {urgency_end}) should be HTML-escaped.
  • urgency_start is a string which replaces the {urgency_start} placeholder in window_format.
  • urgency_end is a string which replaces the {urgency_end} placeholder in window_format.
  • icon_dirs is a vector of directories in which to look for application icons in order to compute the {app_icon} replacement.
  • fallback_icon is a path to some PNG/SVG icon which will be used as {app_icon} if no application-specific icon can be determined.

It is crucial that during selection (using wofi or some other menu program) each window has a different display string. Therefore, it is highly recommended to include the {id} placeholder at least in window_format. Otherwise, e.g., two terminals (of the same terminal app) with the same working directory (and therefore, the same title) wouldn't be distinguishable.

Hint: wofi supports icons with the syntax img:<image-file>:text:<text>, so a suitable window_format with application icon should start with img:{app_icon}:text:.

#Questions & Patches

For asking questions, sending feedback, or patches, refer to my public inbox (mailinglist). Please mention the project you are referring to in the subject.


Bugs and requests can be reported here.

#Build status

builds.sr.ht status


Swayr is licensed under the GPLv3 (or later).