sway
1. Prerequisites
This configuration assumes the following packages are installed:
- Essentials:
sway
is the compositor (user service).swayidle
provides power management (user service).swaylock
provides screen locking functionality (user service).swaybar
provides a status bar which only appears on demand (user service).swaybg
provides wallpaper functionality (user service).foot
is the terminal emulator (user service).systemd
glues everything together (oversees the user services).
- Utilities:
wlsunset
is a gamma adjustment tool (user service).mako
is the notification daemon (user service).fuzzel
, scriptable application launcher.citron
, presents system state via notifications.qutebrowser
, the cutest browser to ever exist.brightnessctl
controls screen backlight.wireplumber
manages multimedia devices (user service).playerctl
controls MPRIS-compliant media players.
2. 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.
2.1. Keys
Define the modifiers and directional keys:
set {
$Super Mod4
$Alt Mod1
$Left h
$Down j
$Up k
$Right l
}
2.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
}
2.3. Modes
set { $session_mode "(L)ock ⋅ (R)eload ⋅ (Q)uit ⋅ (I)nhibit Idle ⋅ (S)uspend ⋅ (H)ibernate ⋅ (P)ower-off" $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.screenshot_mode
: Represents the mode used for getting the system status via notifications.
2.4. Miscellaneous
resize_factor
represents the amount of pixels a particular window should
expand/shrink in size when resized.
set $resize_factor 40px
3. Inputs
For more information on this topic, see sway-input(5).
3.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
.
3.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 one have it any other way.
input "type:touchpad" { tap enabled natural_scroll enabled accel_profile "adaptive" pointer_accel 0.3 }
3.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
4. Outputs
output * resolution 1920x1080@60Hz
5. Keybindings
While this section uses bindsym
to bind keys to commands, it does
also use bindgesture
to bind actions to touchpad gestures.
5.1. Highlighting windows
bindsym {
$Super+$Left focus Left
$Super+$Down focus down
$Super+$Up focus up
$Super+$Right focus right
}
5.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 }
5.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
}
5.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 }
5.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
}
5.6. Window actions
bindsym {
$Super+w kill
$Super+a fullscreen
$Super+o fullscreen disable; floating toggle
$Super+i scratchpad show
$Super+Shift+i move scratchpad
$Super+m layout toggle split tabbed
$Super+Space focus mode_toggle
}
5.7. Playback control
bindsym {
XF86AudioPlay exec playerctl play-pause
XF86AudioNext exec playerctl next
XF86AudioPrev exec playerctl previous
}
5.8. 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
}
5.9. Brightness control
bindsym {
XF86MonBrightnessUp exec brightnessctl set +5%
XF86MonBrightnessDown exec brightnessctl set 5%-
}
5.10. 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
$Super+asterisk mode $screenshot_mode
}
5.11. Applications and menus
bindsym { # Terminal emulator $Super+Return exec swaymsg '[app_id=foot]' focus || footclient $Super+Shift+Return exec footclient # Application launcher $Super+r exec fuzzel --log-level error --prompt "⌘ " # Graphical file manager $Super+n exec swaymsg '[app_id=pcmanfm-qt]' focus || pcmanfm-qt # Text editor $Super+e exec swaymsg '[app_id=emacs]' focus || emacsclient --create-frame $Super+Shift+e exec emacsclient --create-frame # User script that captures a task $Super+t exec capture-task # User script that opens today's journal entry $Super+g exec giornata # User script that copies a password from the password store into the # clipboard via a menu $Super+p exec password-menu # User script that presents the browser's saved sessions via a menu $Super+b exec qutebrowser-sessions }
6. Modes
6.1. Manipulating the graphical 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" i exec swayidle-toggle, mode "default" l exec loginctl lock-session, mode "default" s exec systemctl suspend, mode "default" h exec systemctl hibernate, mode "default" q exec systemctl --user stop sway-session.target, mode "default" p exec systemctl poweroff, mode "default" escape mode "default" }
6.2. Taking screenshots
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 predefined location.
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. 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 font Sans Serif 16 strip_workspace_numbers yes swaybar_command true colors { statusline #FFFFFF background #32323200 inactive_workspace #323232 #323232 #5C5C5C binding_mode #323232 #323232 #ffffff } }
Configure the default workspace layout to be "tabbed" which works really well for my single-screen setup:
workspace_layout tabbed
Configure the default typeface:
font Sans Serif 13
Hide the cursor after a set period of inactivity to reduce distraction:
seat * hide_cursor 10000
Remove any thickness applied to the window borders adjacent to the title and remove the borders adjacent to the window buffer:
set $border_thickness 2 title_align center titlebar_border_thickness 0 titlebar_padding 8 6 hide_edge_borders smart default_border normal $border_thickness
8. Window rules
Window rules allow me to customize the properties of windows declaratively, such properties mainly consist in:
- 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 the idle manager
for_window { [app_id="pinentry-qt"] floating enable, border pixel $border_thickness [app_id="lxqt-policykit-agent"] floating enable, border pixel $border_thickness [app_id="pavucontrol"] floating enable [app_id="org.twosheds.iwgtk|iwgtk"] floating enable [app_id="pcmanfm-qt"] floating enable, sticky enable }
qutebrowser should inhibit the idle manager from allowing the system to sleep when the window is full-screen.
for_window [app_id="qutebrowser|mpv"] { inhibit_idle fullscreen focus }
Capturing a task should overlay the editor on the screen with a slight bit of opacity to allow me to see what's underneath.
for_window [app_id=emacs title="^capture-task$"] { floating enable sticky enable resize set width 900 resize set height 700 move absolute position center border pixel $border_thickness focus }
9. Integration
Given that the compositor is managed by systemd
and that a number of other
services (like wlsunset
, swaybg
and others) 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
hard-coding them) and notify the service manager when it's ready, the latter
will respond to this by starting the other services all while respecting their
sequencing (specified using the After
or Before
directives under
the Unit
section).
exec systemctl --user import-environment WAYLAND_DISPLAY SWAYSOCK XDG_CURRENT_DESKTOP XDG_SESSION_DESKTOP XDG_SESSION_TYPE exec systemd-notify --ready
Force the compositor to ignore requests to load xwayland
because it's not
installed.
xwayland disable
GTK seems to hard-code the fixed width typeface and I like to keep fonts
consistent between applications, one way to do that is to rely on the font
families declared in fontconfig
(as aliases), a program that handles all kinds
of typography settings.
set $schema org.gnome.desktop.interface
exec gsettings set $schema monospace-font-name 'Monospace 10'
Setting the cursor size through gsettings
is the most effective technique.
exec gsettings set $schema cursor-size 24