sway
1. Prerequisites
This configuration assumes that the following packages are installed:
- Essentials:
sway
, obviously.swayidle
, provides power management.swaylock
, provides screen locking.foot
, my terminal emulator of choice.systemd
, for lower-level functionalities, though not a hard requirement.
- Utilities:
wlsunset
, wonderful day/night gamma adjustment tool.light
, to control backlight.pamixer
, to control volume.playerctl
, to control media players.mako
, notification daemon.fuzzel
, scriptable application launcher.i3blocks
, block definition for sway-bar.
- Typeface:
ttf-inconsolata
3. File structure
This configuration is currently laid out as follows:
~/.config/sway/ ├── config ├── rules └── colorschemes/ ├── nord ├── solarized └── zenburn
4. Variable definitions
Variables will make your life easier and you can reference them across
different files, too. To create your own variables, precede them with
$
.
The following variable definitions are used all throughout the configuration, so keep your eyes peeled.
4.1. Keys
Let's define the modifiers and directional keys:
set {
$super Mod4
$alt Mod1
$left h
$down j
$up k
$right l
}
4.2. Workspaces
Switching between workspaces is the most basic operation you will find
yourself doing in a window manager, so why not make it as seamless as
can be. Qtile by default uses "qsdfuiop"
as the default workspace
names, where each character in the aforementioned string represents
the name of an individual workspace and the key to reach it.
I have borrowed this brilliant and intuitive pattern and have been using it ever since, no matter which window manager I find myself using.
set {
$ws1 1:q
$ws2 2:s
$ws3 3:d
$ws4 4:f
$ws5 5:u
$ws6 6:i
$ws7 7:o
$ws8 8:p
}
4.3. Modes
set { $session_mode "(L)ock ⋅ (S)leep ⋅ (R)eload ⋅ (Q)uit" $screenshot_mode "(A)rea ⋅ (O)utput ⋅ (W)indow" }
session_mode
: Represents the mode used for managing the desktop session.screenshot_mode
: Represents the mode used for capturing screenshots.
4.4. Miscellaneous
resize_factor
represents by how many pixels a particular window
should get resized.
set $resize_factor 30px
5. Inputs
For more information on this topic, see sway-input(5).
5.1. Keyboard
You can remap many keys with the use of xkb_options
. For more
information, see xkeyboard-config(1).
input "type:keyboard" {
xkb_layout fr
xkb_options compose:prsc
repeat_rate 50
repeat_delay 300
}
5.2. Touchpad
input "type:touchpad" { tap enabled natural_scroll enabled accel_profile "adaptive" pointer_accel 0.4 }
5.3. Mouse
Move and resize windows with the mouse by holding the $super
key and
the left and right mouse buttons respectively.
floating_modifier $super normal
6. Outputs
I switch between a single and dual screen setup constantly, however my output configuration remains pretty simple.
output * bg #1E5071 solid_color
7. Keybindings
While this section uses bindsym
to bind keys to commands, it does
also use bindgesture
to bind actions to touchpad gestures.
7.1. Highlighting windows
bindsym {
$super+$left focus left
$super+$down focus down
$super+$up focus up
$super+$right focus right
}
7.2. Tiling windows
bindsym { $super+Shift+$left move left $super+Shift+$down move down $super+Shift+$up move up $super+Shift+$right move right } bindgesture { swipe:3:up move up swipe:3:down move down swipe:3:left move left swipe:3:right move right }
7.3. Resizing windows
bindsym {
$super+Control+$left resize shrink width $resize_factor
$super+Control+$down resize shrink height $resize_factor
$super+Control+$up resize grow height $resize_factor
$super+Control+$right resize grow width $resize_factor
}
7.4. Moving between workspaces
bindsym { $super+q workspace $ws1 $super+s workspace $ws2 $super+d workspace $ws3 $super+f workspace $ws4 $super+u workspace $ws5 $super+i workspace $ws6 $super+o workspace $ws7 $super+p workspace $ws8 $super+tab workspace back_and_forth } bindgesture { swipe:4:right workspace prev swipe:4:left workspace next }
7.5. Moving windows between workspaces
bindsym {
$super+shift+q move container to workspace $ws1; workspace $ws1
$super+shift+s move container to workspace $ws2; workspace $ws2
$super+shift+d move container to workspace $ws3; workspace $ws3
$super+shift+f move container to workspace $ws4; workspace $ws4
$super+shift+u move container to workspace $ws5; workspace $ws5
$super+shift+i move container to workspace $ws6; workspace $ws6
$super+shift+o move container to workspace $ws7; workspace $ws7
$super+shift+p move container to workspace $ws8; workspace $ws8
}
7.6. Splitting windows
bindsym {
$super+greater splith
$super+less splitv
$super+m layout toggle all
}
7.7. Window actions
bindsym {
$super+w kill
$super+n fullscreen
$super+b floating toggle
$super+z scratchpad show
$super+space focus mode_toggle
$super+comma sticky toggle
$super+backspace move scratchpad
$super+up opacity plus 0.1
$super+down opacity minus 0.1
}
7.8. Playback control
bindsym {
XF86AudioPlay exec playerctl play-pause
XF86AudioNext exec playerctl next
XF86AudioPrev exec playerctl previous
}
7.9. Volume control
bindsym {
XF86AudioRaiseVolume exec pamixer -i 5
XF86AudioLowerVolume exec pamixer -d 5
XF86AudioMute exec pamixer -t
}
7.10. Brightness control
bindsym {
XF86MonBrightnessUp exec light -A 5
XF86MonBrightnessDown exec light -U 5
}
7.11. Modes
Modes allow us to define keychords, which combine different actions into the same context and are much more ergonomic. The keybindings in this section are merely activators for the listed modes.
bindsym $super+exclam mode $session_mode bindsym $super+asterisk mode $screenshot_mode
7.12. Miscellaneous
bindsym { $super+Return exec footclient $super+Shift+Return exec footclient --app-id=foot-dropdown $super+e exec emacsclient -c $super+0 exec passmenu $super+r exec fuzzel --log-no-syslog }
8. Modes
8.1. Session
Upon entering this mode, I can choose to execute one of many
session-related actions as listed below. I can also cancel at any time
by hitting ESC
.
mode --pango_markup $session_mode bindsym { l exec swaylock, mode "default" s exec systemctl suspend, mode "default" r reload, mode "default" q exit, mode "default" escape mode "default" }
8.2. Screenshot
Upon entering this mode, I have the choice of selecting the kind of screenshot I would like to take, which will then be placed in a standard directory for me to grab.
mode --pango_markup $screenshot_mode bindsym { a exec grimshot save area, mode "default" o exec grimshot save area, mode "default" w exec grimshot save window, mode "default" escape mode "default" }
9. Options
Configure the status bar:
bar { position top # mode hide # modifier $super+shift strip_workspace_numbers yes status_command i3blocks font Inconsolata 12 # colors { # statusline $base00 # separator $base03 # background $base06 # focused_workspace $blue $blue $base06 # inactive_workspace $base06 $base06 $base00 # } }
Configure the default typeface:
font Inconsolata 10
Don't show borders unless there's more than one visible window:
smart_borders on
Declutter the desktop by hiding the cursor after a set period of inactivity:
seat * hide_cursor 10000
10. Colorschemes
This section defines a set of colorschemes which modify the many client properties exposed by sway.
Colorschemes are contained in separate files. Only one may be used at
a time, as they conflict with each other. To start using one,
e.g. solarized
, include the colorschemes/solarized
file.
10.1. Default
This snippet will configure the properties of the status bar; it should be placed inside the bar configuration.
statusline #ffffff background #323232 inactive_workspace #323232 #323232 #5c5c5c
10.2. Solarized
Define the palette:
set { $base03 #002B36 $base02 #073642 $base01 #586E75 $base00 #657B83 $base0 #839496 $base1 #93A1A1 $base2 #EEE8D5 $base3 #FDF6E3 $yellow #B58900 $orange #CB4B16 $red #DC322F $magenta #D33682 $violet #6C71C4 $blue #268BD2 $cyan #2AA198 $green #859900 }
Set the different client properties:
client.focused $base02 $base00 $base02 $green client.focused_inactive $base02 $base03 $base0 client.unfocused $base02 $base03 $base0 client.urgent $yellow $yellow $base03
10.3. Nord
Define the palette:
set { $base06 #2E3440 $base05 #3B4252 $base04 #434C5E $base03 #4C566A $base02 #D8DEE9 $base01 #E5E9F0 $base00 #ECEFF4 $blue #5E81AC $yellow #EBCB8B $orange #D08770 $red #BF616A $magenta #B48EAD $green #A3BE8C }
Set the different client properties:
client.focused $base03 $base03 $base00 $orange client.focused_inactive $base04 $base04 $base00 client.unfocused $base06 $base06 $base00 client.urgent $red $red $red
This snippet defines the properties of the status bar; it should only
be placed inside the bar.colors
directive.
statusline $base00 separator $base03 background $base06 focused_workspace $blue $blue $base06 inactive_workspace $base06 $base06 $base00
10.4. Zenburn
Define the palette:
set { $base00 #292929 $base01 #DCDCCC $base02 #3F3F3F $base03 #DCDCCC $base04 #AB6C71 $base05 #709080 }
Set the different client properties:
client.focused $base01 $base01 $base02 $base02 client.focused_inactive $base02 $base02 $base03 client.unfocused $base02 $base02 $base03 client.urgent $base04 $base04 $base01
11. Imports
Import configurations1 bundled by my distribution:
include /etc/sway/config.d/*
Import the rules
file which defines all the window rules:
include rules
12. Startup
Computers are not very useful without daemons; let's start a few.
Launch wlsunset, a wonderful day/night gamma adjustments utility:
exec wlsunset -l 36.8 -L 10.1 -t 3800 -T 6400
foot supports a server/client architecture, launch the server but don't save any logs in the system journal.
exec foot --server --log-no-syslog
Keeping a device on for extended periods of time can be a security
nightmare and a total battery-drainer. swayidle
allows us to tell it
what to do, and at which stages.
I've set it up to behave the following way:
- Lock the screen after 5 minutes of inactivity.
- Turn off the screen after another 3 minutes.
- Suspend the system after another 12 minutes.
The screen will also lock itself upon suspension, e.g. when closing the laptop's lid.
Timers are started simultaneously, which is why the timeout values are the way they are.
exec swayidle -w \ timeout 300 'swaylock' \ timeout 480 'swaymsg "output * dpms off"' \ resume 'swaymsg "output * dpms on"' \ timeout 1020 'systemctl suspend' \ before-sleep 'swaylock'
Launch the authentication agent which allows applications to escalate their privileges in a secure manner when required:
exec --no-startup-id /usr/bin/lxqt-policykit-agent
Every other daemon is started as a user service with systemctl(1)
.
13. Window rules
Window rules allow me to customize the properties of windows programmatically, such properties include:
- The location of said windows:
- XY coordinates and/or which workspace they belongs to
- Their geometry and decorations
- Their effect on the window manager:
- Inhibiting sleep
- And so much more
Define what workspaces certain applications should appear in:
for_window [app_id="emacs"] move window to workspace $ws3; focus for_window [app_id="org.pwmt.zathura"] move window to workspace $ws4; focus for_window [app_id="mpv"] move window to workspace $ws5; focus for_window [app_id="virt-manager"] move window to workspace $ws7; focus for_window [app_id="signal"] move window to workspace $ws8
Define which applications should float:
for_window [app_id="pinentry-qt"] floating enable for_window [app_id="lxqt-policykit-agent"] floating enable for_window [app_id="pavucontrol"] floating enable
Define some window rules for Firefox such that it appears in the same workspace every time as well as inhibit sleep when the window is in fullscreen mode.
for_window [app_id="firefox"] { move window to workspace $ws1 inhibit_idle fullscreen focus }
Define the appearance and geometry of Picture-in-Picture windows. This article explains the rationale behind the settings of this window rule.
for_window [title="^Picture-in-Picture$"] { floating enable sticky enable border none move position 1420 800 resize set height 280px resize set width 500px opacity 0.7 }
Terminals should default to tabbed mode by default, this eases navigating between them and ensures that text doesn't get wrapped.
for_window [app_id="^foot$"] { move window to workspace $ws2 focus }
It's nice to be able to pop open a terminal right where you are, kind of a like those dropdown terminals.
for_window [app_id="^foot-dropdown$"] { move scratchpad scratchpad show floating enable sticky enable border none resize set height 500px resize set width 1920px move position 0 0 opacity 0.9 }
There comes a time when a GUI file manager is really useful.
for_window [app_id="pcmanfm-qt"] { floating enable sticky enable }
for_window [app_id="(org.twosheds.iwgtk|iwgtk)"] floating enable
Footnotes
Different distributions package their software differently, verify that the directory exists and is populated.