--- /dev/null
+#! /bin/bash
+#
+# bspwm-session
+#
+# This script is a session launcher for bspwm.
+# It is based on similar scripts included with Openbox.
+
+if [ -n "$1" ]; then
+ echo "Usage: bspwm-session"
+ echo
+ exit 1
+fi
+
+# Multi-user support:
+state_prefix=${XDG_CACHE_HOME:-"$HOME/.cache"}
+mkdir -p "${state_prefix}"
+
+if [ ! -d "${state_prefix}" ]; then
+ echo "bspwm-session: cache directory ‘${state_prefix}‘ is missing."
+ echo
+ exit 1
+elif [ ! -w "${state_prefix}" ]; then
+ echo "bspwm-session: cache directory ‘${state_prefix}‘ is not writable."
+ echo
+ exit 1
+fi
+
+state_path=$(mktemp -d "${state_prefix}/bspwm-session.XXXXXX")
+
+if [ $? -ne 0 ]; then
+ echo "bspwm-session: failed to create state directory ‘${state_path}‘."
+ echo
+ exit 1
+fi
+
+export BSPWM_SOCKET=${state_path}/bspwm-socket
+export PANEL_FIFO=${state_path}/panel-fifo
+
+mkfifo "${PANEL_FIFO}"
+
+# Trap: make sure everything started in ~/.config/bspwm/autostart is
+# signalled when this script exits or dies. Also clean up $state_path.
+function on_exit {
+for child in $(jobs -p); do
+ jobs -p | grep -q $child && kill $child
+done
+# Extra paranoia
+[[ -d "${state_path}" && -w "${state_path}" ]] && rm -rf -- "${state_path}"
+}
+
+trap on_exit EXIT SIGHUP SIGINT SIGTERM
+
+# Environment and autostart:
+source_these=(
+"/etc/profile",
+"${HOME}/.profile",
+"${XDG_CONFIG_HOME:-"$HOME/.config"}/bspwm/autostart"
+)
+
+for file in "${source_these[@]}"; do
+ [ -r "${file}" ] && . "${file}"
+done
+
+# Launch sxhkd:
+sxhkdrc_path=${XDG_CONFIG_HOME:-"$HOME/.config"}/bspwm/sxhkdrc
+[ -r "${sxhkdrc_path}" ] && sxhkd -c "${sxhkdrc_path}" &
+
+# Launch bspwm:
+bspwm -s "${PANEL_FIFO}" -p W