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 + Enter
Mod4 + d
Mod4 + q
Mod4 + c
Mod4 + f
Mod1 + Tab
Mod4 + 1,2..6
Mod4 + Shift + 1,2..6
Rebuild 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 + Enter
Mod4 + d
Mod4 + q
Mod4 + c
Mod4 + f
Mod1 + Tab
Mod4 + 1,2..6
Mod4 + Shift + 1,2..6
Mod4 + shift + f
Mod4 + shift + e
Mod4 + shift + w
Mod4 + shift + x
Mod4 + x
Mod4 + s
and 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!