05 Dec 2019
I've been an i3wm user for a long time now. But everyonce in a while I get annoyed with writing floating rules for programs that look far-fetched in tiling mode.
Like many others, my first fore into plain window manager desktops was with openbox and
crunchbang. So I decided to go back to
openbox. And I was happy... for a while. The menus and configuring openbox without obconf
is a nightmare. Then one fine day, while scrolling through
r/unixporn, I saw a
post
from Dylan Araps, of neofetch fame. It turns out he made a
bare-bones floating window manager called sowm and has even
started a minimal linux distro called KISS. sowm, like dwm is configured
at compile-time and the defaults make sense.
Knowing Dylan and the quality of work he does, I had to give this a try!
This post is my personal sowm setup running on top of voidlinux. But the
same can be done on any distro.
tmux.Mod4+1,2...0 for workspace navigation.To build sowm or any wm, we'll need the x11 dev libraries(just xlib for sowm).
Do an # xbps-install libX11-devel to have those installed in our machine.
It goes without saying that gcc and make should also be present.
$ git clone https://github.com/dylanaraps/sowm
$ cd sowm
All my personal programs are in $HOME/bin. Having the following line in $HOME/.profile
[ -d $HOME/bin ] && export PATH="${HOME}/bin:${PATH}"
will add the programs/scripts in that bin folder to my $PATH. So when I install sowm,
I need it to go here. Open up the Makefile and change the PREFIX and BINDIR variables.
PREFIX?= /home/username
BINDIR?= $(PREFIX)/bin
To install, run
$ make
$ make install
This will build the sowm binary and put it in $HOME/bin.
There is a config.h file in the clonned folder. If not, make one by copying over the
config.def.h file. This file holds the keybinds, sowm uses.
There are keybinds for starting a terminal, changing brightness and some others. But, I'd
like to use a separate program for controlling the keybindings called sxhkd. Voidlinux
has it in the default repos. So my config.h looks like
#ifndef CONFIG_H
#define CONFIG_H
#define MOD Mod4Mask
const char* menu[] = {"wm_run", 0};
const char* term[] = {"xst", 0};
static struct key keys[] = {
{MOD, XK_q, win_kill, {0}},
{MOD, XK_c, win_center, {0}},
{MOD, XK_f, win_fs, {0}},
{Mod1Mask, XK_Tab, win_next, {0}},
{MOD, XK_Return, run, {.com = term}},
{MOD, XK_d, run, {.com = menu}},
{MOD, XK_1, ws_go, {.i = 1}},
{MOD|ShiftMask, XK_1, win_to_ws, {.i = 1}},
{MOD, XK_2, ws_go, {.i = 2}},
{MOD|ShiftMask, XK_2, win_to_ws, {.i = 2}},
{MOD, XK_3, ws_go, {.i = 3}},
{MOD|ShiftMask, XK_3, win_to_ws, {.i = 3}},
{MOD, XK_4, ws_go, {.i = 4}},
{MOD|ShiftMask, XK_4, win_to_ws, {.i = 4}},
{MOD, XK_5, ws_go, {.i = 5}},
{MOD|ShiftMask, XK_5, win_to_ws, {.i = 5}},
{MOD, XK_6, ws_go, {.i = 6}},
{MOD|ShiftMask, XK_6, win_to_ws, {.i = 6}},
};
#endif
xst is my terminal and wm_run is simply a wrapper script around dmenu_run. Here's the
content of $HOME/bin/wm_run
#!/bin/sh
dmenu_run \
-p "Run:" -l 10 -fn "Monospace:size=10"
So sowm manages,
Mod4 + EnterMod4 + dMod4 + qMod4 + cMod4 + fMod1 + TabMod4 + 1,2..6Mod4 + Shift + 1,2..6Rebuild the binary with,
$ make clean
$ make
$ make install
I run my X session with startx. So to start sowm, I put it in my $HOME/.xinitrc. Here's a simple
.xinitrc file, that I use.
#!/bin/sh
# kill wm session with Ctrl + Alt + Backspace
setxkbmap -option terminate:ctrl_alt_bksp
xrdb -merge $HOME/.Xresources
xset b off
xset r rate 250 25
xsetroot -cursor_name left_ptr
# startup programs, the & means background it
dunst & # notification daemon
sxhkd & # keyboard shortcut daemon
xautolock -time 10 -locker "slock" &
# start sowm
exec ck-launch-session dbus-launch sowm
# I have pulseaudio installed and dbus is a strict dependency!
# you can replace the above line with just
# exec sowm
setxkbmap is used to map keys. For example, swapping Capslock and Esc keys. dunst is a simple notification daemon. xautolock will automatically lock screen after x mins of inactivity.sowm entry. Make sure a & is
at the end for each entry. If you use feh or nitrogen for setting a wallpaper, add those here too.Another way people run X sessions is via a Display Manager like lightdm. In that case,
our .xinitrc is pointless. Special thanks to koutsie and
Leon-Plicat, for the info.
Discussion can be found here. If you use a login
manager, then use the following method and not .xinitrc.
Start by making a executable start_sowm.sh in your $HOME/bin. It's an exact copy of our
.xinitrc
#!/bin/sh
# kill wm session with Ctrl + Alt + Backspace
setxkbmap -option terminate:ctrl_alt_bksp
xrdb -merge /home/youruser/.Xresources
xset b off
xset r rate 250 25
xsetroot -cursor_name left_ptr
# startup programs, the & means background it
dunst & # notification daemon
sxhkd & # keyboard shortcut daemon
xautolock -time 10 -locker "slock" &
# start sowm
exec /home/youruser/bin/sowm
Next make a /usr/share/xsessions/sowm.desktop file. The content is
[Desktop Entry]
Name=sowm
Exec=/home/youruser/bin/start_sowm.sh
Comment=Bootstrap script for sowm
Type=Application
Logout and you should see an entry for sowm.
wm_run will be invoked via Mod4 + d. We can launch apps via that menu. But, having a few nifty
keybinds that launch handy tools and operations is a plus. And thats where sxhkd comes in.
Here's my $HOME/.config/sxhkd/sxhkdrc file.
# programs I use
super + shift + e
code-oss
super + shift + f
thunar
super + shift + w
firefox
# a bar replacement ?
super + s
wm_notify_pop
# lock screen
super + x
slock
# exit menu
super + shift + x
wm_session_exit
# make sxhkd reload its configuration files
super + shift + Escape
pkill -USR1 -x sxhkd; \
notify-send "reloaded sxhkd"
XF86AudioMute
pactl set-sink-mute 0 toggle
XF86AudioRaiseVolume
pactl set-sink-volume 0 +5%
XF86AudioLowerVolume
pactl set-sink-volume 0 -5%
XF86AudioMicMute
pactl set-source-mute 1 toggle
XF86MonBrightnessUp
xbacklight +10
XF86MonBrightnessDown
xbacklight -10
The config file is in plain english!. The programs starting with wm_* are custom scripts in
$HOME/bin, the others are installable via our distro's package manager.
wm_notify_pop is a pop-up replacement for a bar. Technically I'm cheating by using a notification,
but it works. Here it is, in all its glory.
#!/bin/sh
BAT="BAT0"
STATUS=$(cat /sys/class/power_supply/$BAT/status)
PERCENT=$(cat /sys/class/power_supply/$BAT/capacity)%
BAT_STATUS=$(echo $STATUS $PERCENT)
DATE=$(date +"%a %b %e %H:%M")
# putting it all together
notify-send "$BAT_STATUS | $DATE"
Here's the wm_session_exit, an another wrapper around dmenu
#!/bin/bash
DMENU='dmenu -i -fn Monospace:size=10 -p > '
choice=$(echo -e "poweroff\nreboot" | $DMENU)
case "$choice" in
poweroff) sudo poweroff;;
reboot) sudo reboot;;
esac
For the above script to work, I have an entry for my $USER in the
sudoers file. Invoke $ sudo visudo and put the following at the end.
username ALL=NOPASSWD: /bin/poweroff, /bin/reboot
With this, we should have a minimal but functional sowm powered desktop session. Just as a summary,
here is the list of keybinds
Mod4 + EnterMod4 + dMod4 + qMod4 + cMod4 + fMod1 + TabMod4 + 1,2..6Mod4 + Shift + 1,2..6Mod4 + shift + fMod4 + shift + eMod4 + shift + wMod4 + shift + xMod4 + xMod4 + sand the mouse controls are,
Mod4 and left-click + drag.Mod4 and right-click + drag.As a bonus, here's a not so exciting screenshot of the fruits of our labor.
Note: sowm is still actively being worked on. So keep track of its github
issues. If you run into any problems,
raise an issue there or feel free to email me.
I hope you'd give this workflow and sowm a try.
Happy hacking and have a great day!