dotfiles/herbstluftwm/.config/herbstluftwm/autostart

246 lines
8.6 KiB
Bash
Executable file

#!/usr/bin/env zsh
## Helper functions:
# This simple function saves a lot of keystrokes when editing this
# configuration. Instead of typing "herbstluftwm" everywhere, I can
# just type "hc". This is part of the default configuration.
function hc() { herbstclient "$@"; }
# This function picks a random wallpaper from a list collection.
function random-wallpaper() {
find ~/pictures/wallpapers -type f \
-wholename '*/3840x1080/*' -o -wholename '*/patterns/*' \
| shuf -n 1
}
# This function adds an attribute to a herbstluftwm tag that tells it
# which monitor it should appear on, in case I care. Usually I want
# Emacs and my terminal to always appear on my primary monitor, and
# Conkeror/Firefox on my secondary, I don't like it when they get
# switched.
function lock-tag-to-monitor() {
herbstclient chain \
, new_attr string tags.by-name."$1".my-monitor \
, set_attr tags.by-name."$1".my-monitor "$2"
}
## Reload hook:
# According to the herbstluftwm man page this hook is emitted so that
# daemons will know to quit and it should be emitted first thing.
hc emit_hook reload
## Background image:
# Set a random image as the desktop wallpaper.
feh --bg-tile "$(random-wallpaper)"
## Keybindings:
# Remove all existing keybindings so that when herbstluftwm is
# restarted, no keybindings get accidentally left active if they've
# been removed.
hc keyunbind --all
# Use the super key as the main modifier, Alt (Mod1) is used by too
# many other applications (Emacs and Zsh for example) to really be
# useful.
Mod=Mod4
# These are dangerous keybindings, they could be very annoying if
# they're accidentally pressed, so using Shift here to make it a
# little less easy to do this is a good idea.
hc keybind $Mod-Shift-q quit
hc keybind $Mod-Shift-r reload
# Usually I close the applications I use through a menu or keybinding
# inside the application, but not all applications offer
# this. Sometimes need to tell the window manager to do so.
hc keybind $Mod-k close
# Normally I try to have frames set-up the way I like them
# programmatically, not manually, but sometimes I need to do it
# manually anyway and remove them afterwards.
hc keybind $Mod-Shift-k remove
# Always spawn an instance of URxvt.
hc keybind $Mod-Return spawn urxvt
# Switch to a running instance of URxvt, or start one.
hc keybind $Mod-c spawn hlwm-run-or-raise URxvt urxvt
# Switch to a running instance of Conkeror, or start one.
hc keybind $Mod-b spawn hlwm-run-or-raise Conkeror conkeror
# Switch to a running instance of Emacs, or create an Emacs client
# frame. Start an Emacs daemon if necessary.
hc keybind $Mod-t spawn hlwm-run-or-raise Emacs \
emacsclient --create-frame --alternate-editor=''
# Lock the screen with C-M-l.
hc keybind Control-Mod1-l spawn i3lock --color 000000
# Swap visible tags
hc keybind $Mod-x spawn hlwm-switch-tags
# Since I use the colemak keyboard layout, hjkl doesn't make much
# sense. I use neio instead since that is almost in the same place
# (though one place to the right). I try to use my run-or-raise script
# as much as I can, and have the layouts set-up correctly already, but
# sometimes I still need to move around, resize and move clients.
resizestep=0.05
hc keybind $Mod-n focus left
hc keybind $Mod-e focus down
hc keybind $Mod-i focus up
hc keybind $Mod-o focus right
hc keybind $Mod-Shift-n shift left
hc keybind $Mod-Shift-e shift down
hc keybind $Mod-Shift-i shift up
hc keybind $Mod-Shift-o shift right
hc keybind $Mod-Control-n resize left +$resizestep
hc keybind $Mod-Control-e resize down +$resizestep
hc keybind $Mod-Control-i resize up +$resizestep
hc keybind $Mod-Control-o resize right +$resizestep
# I usually try to have my layouts set-up programmatically, but this
# isn't always possible or practical.
hc keybind $Mod-s split bottom 0.5
hc keybind $Mod-Shift-s split right 0.5
# Switching tags by number (key) isn't always practical, sometimes
# switching to next/previous tag is easiest.
hc keybind $Mod-period use_index +1 --skip-visible
hc keybind $Mod-comma use_index -1 --skip-visible
# Games and sometimes other applications don't always like being
# forced into a strangely sized box, floating mode helps.
hc keybind $Mod-Control-f floating toggle
# Playing games in fullscreen mode can end badly by having the game
# spread across both monitors. Also watching a twitch stream with lots
# of text is best in fullscreen.
hc keybind $Mod-f cycle_layout 1 vertical max
hc keybind $Mod-Shift-f fullscreen toggle
hc keybind $Mod-p pseudotile toggle
# The following cycles through the available layouts within a frame, but skips
# layouts, if the layout change wouldn't affect the actual window positions.
# I.e. if there are two windows within a frame, the grid layout is skipped.
hc keybind $Mod-space \
or , and . compare tags.focus.curframe_wcount = 2 \
. cycle_layout +1 vertical horizontal max vertical grid \
, cycle_layout +1
# mouse
hc mouseunbind --all
hc mousebind $Mod-Button1 move
hc mousebind $Mod-Button2 zoom
hc mousebind $Mod-Button3 resize
# focus
hc keybind $Mod-BackSpace cycle_monitor
hc keybind $Mod-Tab cycle_all +1
hc keybind $Mod-Shift-Tab cycle_all -1
# Use u because i is already used by by navigation commands.
hc keybind $Mod-u jumpto urgent
# Add some media key bindings for MPD.
hc keybind XF86AudioPlay spawn mpc toggle
hc keybind XF86AudioNext spawn mpc next
hc keybind XF86AudioPrev spawn mpc prev
# Change the default layout to fullscreen.
hc set default_frame_layout 2
## Tags:
tag_names=( dev web {3..10} )
tag_indexes=( {1..${#tag_names}} )
tag_keys=( bracketleft braceleft braceright parenleft equal
asterisk parenright plus bracketright exclam )
hc rename default "${tag_names[1]}" || true
for i in $tag_indexes; do
hc add "${tag_names[$i]}"
key="${tag_keys[$i]}"
if ! [ -z "$key" ] ; then
# ZSH array indexes start at 1, herbstluftwm tag indexes start
# at zero, so subtract one to match them.
j=$(( $i - 1 ))
# first check if the tag is locked to some monitor.
# if so, first focus the monitor
hc keybind "$Mod-$key" chain \
, silent substitute M tags."$j".my-monitor focus_monitor M \
, use_index "$j"
hc keybind "$Mod-Shift-$key" move_index "$j"
fi
done
# theme
hc attr theme.tiling.reset 1
hc attr theme.floating.reset 1
hc set frame_border_active_color '#3d3d3d'
hc set frame_border_normal_color '#222222'
hc set frame_bg_normal_color '#111111'
hc set frame_bg_active_color '#263f1f'
hc set frame_border_width 0
hc set window_border_width 2
hc set window_border_inner_width 0
hc set window_border_normal_color '#222222'
hc set window_border_active_color '#3d3d3d'
hc set window_border_inner_color '#111111'
hc set always_show_frame 0
hc set frame_gap 30
# Add overlapping window borders
hc set window_gap 30
hc set frame_padding -30
hc set frame_bg_transparent 1
hc set smart_window_surroundings 0
hc set smart_frame_surroundings 0
hc set mouse_recenter_gap 0
hc set swap_monitors_to_get_tag 0
hc set update_dragged_clients 1
# rules
hc unrule -F
hc rule focus=on # normally focus new clients
hc rule class=Emacs tag=dev index=0 switchtag=on hook=emacs
hc rule class=URxvt tag=dev index=1 switchtag=on hook=urxvt
hc rule class~'Conkeror|Firefox' tag=web index=0
hc rule class=Pinentry pseudotile=on
hc rule class=Alsaplayer pseudotile=on
hc rule windowtype~'_NET_WM_WINDOW_TYPE_(DIALOG|UTILITY|SPLASH)' pseudotile=on
hc rule windowtype='_NET_WM_WINDOW_TYPE_DIALOG' focus=on
hc rule windowtype~'_NET_WM_WINDOW_TYPE_(NOTIFICATION|DOCK|DESKTOP)' manage=off
# unlock, just to be sure
hc unlock
herbstclient set tree_style '╾│ ├└╼─┐'
## Monitors
# I have two monitors, each with a resolution of 1920x1080.
hc set_monitors 1920x1080+0+0 1920x1080+1920+0
# Pad the first monitor to make room for mowedline and trayer.
hc pad 0 0 0 16 16
# Load layouts for the dev and web tags.
hc load dev '(split horizontal:0.535:1 (clients max:0) (clients vertical:0))'
hc load web '(clients max:0)'
# Make sure the "Emacs" frame is selected.
hc focus_edge left
# Lock each tag to its specific monitor.
lock_tag_to_monitor dev 0
lock_tag_to_monitor web 1
## Other configurations
# Load any other configuration files in
# $HOME/.config/herbstluftwm/autostart.d so other programs can
# configure parts of herbstluftwm to their needs (such as keybindings
# for Rofi).
if [ -d "${HOME}/.config/herbstluftwm/autostart.d" ]; then
for f in ${HOME}/.config/herbstluftwm/autostart.d/?*.sh; do
[ -x "$f" ] && source "$f"
done
unset f
fi