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.wireplumber
, to manage audio devices.playerctl
, to control media players.mako
, notification daemon.fuzzel
, scriptable application launcher.
- 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 make my life easier and they can be referenced across different files, too. The following variable definitions are used all throughout this configuration to preserve a level of consistency that could not be achieved otherwise.
4.1. Keys
Define the modifiers and directional keys:
set {
$Super Mod4
$Alt Mod1
$Left h
$Down j
$Up k
$Right l
}
4.2. Workspaces
Moving between workspaces is the most common operation one does in a
window manager so their key placement should be very convenient. Qtile
happens to utilize a layout that is particularly easy to remember, by
default it uses "qsdfuiop"
as the default workspace names, each
character being the name of an individual workspace and the key to
reach it. I have borrowed this intuitive pattern and have been using
it ever since, no matter the window manager.
set {
$ws1 1:q
$ws2 2:s
$ws3 3:d
$ws4 4:f
}
4.3. Modes
set { $session_mode "(L)ock ⋅ (S)leep ⋅ (R)eload ⋅ (Q)uit" $screenshot_mode "(A)rea ⋅ (O)utput ⋅ (W)indow" $citron_mode "(D)ate ⋅ (B)attery" }
session_mode
: Represents the mode used for managing the desktop session.screenshot_mode
: Represents the mode used for capturing screenshots.screenshot_mode
: Represents the mode used for getting the system status via notifications.
4.4. Miscellaneous
resize_factor
represents the amount of pixels a particular window
should expand/shrink in size when resizing it.
set $resize_factor 40px
5. Inputs
For more information on this topic, see sway-input(5).
5.1. Keyboard
It is possible to remap many keys and fool around with different
keyboard layouts and formats using xkb_options
, for more
information, see xkeyboard-config(1).
input "type:keyboard" {
xkb_layout fr
xkb_options compose:prsc
repeat_rate 50
repeat_delay 250
}
It's very helpful, especially in text editors, to have a very short
repeat_delay
and a very high repeat_rate
.
5.2. Touchpad
Nothing fancy is going on here, just natural scrolling as if one is paging through a book and adaptive acceleration because why would you have it any other way.
input "type:touchpad" { tap enabled natural_scroll enabled accel_profile "adaptive" pointer_accel 0.3 }
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. Keybindings
While this section uses bindsym
to bind keys to commands, it does
also use bindgesture
to bind actions to touchpad gestures.
6.1. Highlighting windows
bindsym {
$Super+$Left focus Left
$Super+$Down focus down
$Super+$Up focus up
$Super+$Right focus right
}
6.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 }
6.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
}
6.4. Moving between workspaces
bindsym { $Super+q workspace $ws1 $Super+s workspace $ws2 $Super+d workspace $ws3 $Super+f workspace $ws4 $Super+tab workspace back_and_forth } bindgesture { swipe:4:right workspace prev swipe:4:left workspace next }
6.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
}
6.6. Splitting windows
bindsym {
$Super+greater splith
$Super+less splitv
$Super+u layout toggle all
}
6.7. Window actions
bindsym {
$Super+w kill
$Super+n fullscreen
$Super+b fullscreen disable; floating toggle
$Super+o scratchpad show
$Super+Space focus mode_toggle
$Super+asciicircum sticky toggle
$Super+Shift+o move scratchpad
}
6.8. Playback control
bindsym {
XF86AudioPlay exec playerctl play-pause
XF86AudioNext exec playerctl next
XF86AudioPrev exec playerctl previous
}
6.9. Volume control
bindsym {
XF86AudioRaiseVolume exec wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 0.05+
XF86AudioLowerVolume exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.05-
XF86AudioMute exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
}
6.10. Brightness control
bindsym {
XF86MonBrightnessUp exec light -A 5
XF86MonBrightnessDown exec light -U 5
}
6.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 bindsym $Super+i mode $citron_mode
6.12. Miscellaneous
bindsym { $Super+Return exec footclient $Super+Shift+Return exec swaymsg '[app_id=foot-dropdown]' focus || footclient --app-id=foot-dropdown $Super+Shift+e exec emacsclient -c $Super+e exec swaymsg '[app_id=emacs]' focus || emacsclient -c $Super+p exec passmenu $Super+r exec fuzzel --log-level error --lines 6 --prompt "⌘ " $Super+y exec qutebrowser-sessions }
7. Modes
7.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 $session_mode bindsym { r reload, mode "default" l exec loginctl lock-session, mode "default" s exec systemctl suspend, mode "default" q exec systemctl stop --user sway, mode "default" escape mode "default" }
7.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 $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" }
7.3. Citron
This mode allows me to display various details relating to the status of my computer (for example, network, battery and uptime statistics) in the form of a notification.
mode $citron_mode bindsym { b exec citron battery, mode "default" d exec citron date, mode "default" escape mode "default" }
8. Options
The status bar is configured to display only if the Super
modifier
is held, its primary role is to guide me as I navigate between
workspaces which makes Super
the most convenient and sensible
modifier to use.
The philosophy here is that the status bar is less of an information center and more of a navigational guide.
bar { mode hide position bottom strip_workspace_numbers yes font Inconsolata 12 swaybar_command true colors { statusline #ffffff background #32323200 inactive_workspace #323232 #323232 #5C5C5C binding_mode #323232 #323232 #ffffff } }
Configure the default font to match that of the bar:
font Inconsolata 12
Declutter the desktop by hiding the cursor after a set period of inactivity:
seat * hide_cursor 10000
Disable Xwayland rather than having it lie dormant:
xwayland disable
Remove any thickness applied to the window borders:
titlebar_border_thickness 0
9. 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.
9.1. Default
This snippet will configure the properties of the status bar; it
should be placed inside the bar
directive.
statusline #ffffff background #32323200 inactive_workspace #323232 #323232 #5C5C5C binding_mode #323232 #323232 #ffffff
9.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
9.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 be
placed inside the bar.colors
directive.
statusline $base00 separator $base03 background $base06 focused_workspace $blue $blue $base06 inactive_workspace $base06 $base06 $base00
9.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
10. Imports
Import the rules
file which defines all the window rules:
include rules
11. Window rules
Window rules allow me to customize the properties of windows programmatically, such properties include:
- The location of said windows:
(X,Y)
coordinates and/or the workspace to which they belong
- Their geometry and decorations
- Their effect on the compositor:
- Inhibiting sleep
- And so much more
for_window [app_id="pinentry-qt"] floating enable for_window [app_id="lxqt-policykit-agent"] floating enable for_window [app_id="pavucontrol"] floating enable for_window [app_id="org.twosheds.iwgtk|iwgtk"] floating enable for_window [app_id="foot"] inhibit_idle fullscreen
Qutebrowser should inhibit idle (meaning the system will not go to sleep) when the window is fullscreen.
for_window [app_id="qutebrowser"] { inhibit_idle fullscreen focus }
It's nice to be able to pop open a terminal right where you are, kind of like those dedicated dropdown terminal emulators.
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 }
12. Integration
Given that the compositor is managed by systemd
and that a number of
other services, like wlsunset
, swaybg
, etc., require certain
environment variables (for example, WAYLAND_DISPLAY
) to be set in
order to function properly, the compositor must therefore expose these
two variables (without hardcoding them) and notify the service manager
when it's ready, the latter will respond to this by starting the other
services all the while respecting their sequencing (specified using
the After
or Before
directive under the Unit
section of
.service
files).
exec systemctl --user import-environment WAYLAND_DISPLAY SWAYSOCK exec systemd-notify --ready