#
# SXHKD module with WM-agnostic keys
#
# ~/.config/sxhkd/sxhkdrc
#
# Other modules should be available at ~/.config/sxhkd/
#

# Description
# ===========
#
# Partial configuration file for the Simple X Hotkey Daemon.  Meant to
# work with `bspwm`.  This is part of my dotfiles, which are managed
# with GNU Stow.  See https://gitlab.com/protesilaos/dotfiles
#
# Last full review on 2019-05-23



# Index with key chord chain mnemonics
# ====================================
#
# Key chord chains are used for less common or ancillary commands, or
# for when assigning direct keybindings would become unwieldy.  The idea
# is to scope bindings so as to avoid conflicts.
#
# Environment: super + e ; ...
# Executables which typically run in the console: super + x ; ...
# Graphical applications: super + g ; ...
# Assign (node flags): super + a ; ...
# Split (split ratios): super + s ; ...



# Keyboard layout
# ---------------
# We can set the keyboard layouts, as well as the toggle directly via
# `setxkbmap`.  Example of what I used to run:
#
#	setxkbmap -layout 'us,gr' -option 'grp:alt_caps_toggle'
#
# However, doing so means losing out on the possibility to easily find
# out the current/active layout from a script: X knows about "us,gr" in
# that order, not which one is currently typing.  As such, in `bspwmrc`
# I simply autostart `setxkbmap -layout 'us'` without defining the
# second layout and a toggle.  The toggle is set below.  With the
# difference being that it invokes a custom script that switches between
# the us,gr layout.  All this is done to be able to get the active
# keyboard layout and print its name to my system panel (custom lemonbar
# called "melonpanel").
{alt + Caps_Lock,super + Escape}
	own_script_current_keyboard_layout

# Environment
# -----------

# The following commands are:
#
# c == toggle compton (display compositor)
# d == dmenu to quickly edit dotfiles
# f == bspwm focus mode
# s == reload sxhkd
# p == reload melonpanel (my lemonbar script)
# t == dmenu to choose Tempus theme
# m == notification with mpc status (shows album art, title, etc.)
# k == toggle screenkey (useful for screen casts)
# q == dmenu interface to log out, lock, switch users, reboot, shutdown
# x == reload the Xresources file
#
# Recall that these depend on my dotfiles:
# https://gitlab.com/protesilaos/dotfiles.
super + e ; {c,d,f,s,p,t,m,k,q,x}
	{ \
	toggle_compton, \
	dotsmenu, \
	bspwm_focus_mode, \
	pkill -USR1 -x sxhkd && notify-send -i debian-logo "sxhkd config" "Reloaded key bindings", \
	pkill -x melonpanel && melonpanel, \
	tempusmenu, \
	own_script_notify_send_mpc_status, \
	toggle_screenkey, \
	poweroptionsmenu, \
	xrdb -I "$HOME" -merge "$HOME"/.Xresources \
	}

# Session management (log out, lock, switch users, reboot, shutdown).
# Can also be invoked with super + e ; q (as defined above).
ctrl + alt + {Home,End,Delete}
	poweroptionsmenu

# Main programs
# -------------

# Terminal emulator with and without TMUX.  I normally use `tmux` which
# is ideal for working on multiple terminals, switching sessions, and
# the like.  I think it fits perfectly into a console-based workflow and
# complements the features of a tiling WM.  No need to spawn tens of
# terminals, like a barbarian!  Watch my screen cast on the matter:
# https://protesilaos.com/codelog/2019-01-13-tmux-demo-bspwm/
super + {_, shift + } Return
	{xterm -e tmux new-session -A -s 'Default', xterm}

# GUI programs.  Where these are alternatives to common CLI tools they
# are mapped to the same number as their counterparts, but prepended
# with a `g` (mnemonic for GUI).
super + g ; {1,2,3}
	{ \
	notify-send -i firefox "Run GUI program" "Launching Web Browser" && firefox-esr, \
	notify-send -i system-file-manager "Run GUI program" "Launching File Manager" && caja, \
	notify-send -i thunderbird "Run GUI program" "Launching Email Client" && thunderbird \
	}

# CLI programs.  Any browser and/or file manager should be assigned the
# numbers 1 and 2 respectively, in order to keep consistency with the
# above-defined GUIs.
super + x ; {3-5}
	xterm -e {mutt,newsboat,ncmpcpp}

# I use "my_float_window" as an application name or class for those rare
# occasions where I prefer a floating window at launch.
#
# Note that the executable `calc` is contained in the Debian package
# `apcalc`.
super + x ; 0
	xterm -class "my_float_window" -e calc

# Bring up the help text for common keybindings
super + {F1,Home}
	xterm -class "my_float_window" \
	-geometry '100x30' -e less "$HOME/.config/sxhkd/cheatsheet_sxhkdrc.txt"

# sbgmenu: dmenu interface for browsing images from my "Pictures"
# directory.  There is an option to just display the selected file, or
# set it as the new desktop wallpaper.
#
# nbm: similar to the above, but uses a graphical approach, by
# displaying all image thumbnails in a grid layout using `sxiv`.  The
# user can view each image individually and mark images.  If only one is
# marked, it is defined as the new wallpaper, else another grid is drawn
# with just the marked files.
#
# Watch this screen cast for `sbgmenu` and `nbm`:
# https://protesilaos.com/codelog/2019-02-09-unix-ways-wallpapers/
#
# stmmenu: dmenu interface for managing my task list.  If I type
# something that has no match, it is appended in plain text format to my
# task list file.  If I select an existing item, it is removed from the
# list.  I also have a script that presents the data: see "stm" inside
# my dotfiles' "bin" directorty.  Check this video demo:
# https://protesilaos.com/codelog/2019-02-17-unix-ways-todo/
#
# NOTE the keys are mnemonics for Backgrounds, Wallpapers, Tasks.
super + x; {b,w,t}
	{sbgmenu,nbm,stmmenu}

# dmenu_run and passmenu using my custom colours.
super + {d,p}
	{own_script_run_dmenu_xcolors,own_script_run_passmenu_xcolors}

# dmenu specifically for flatpaks.  While it is possible to include
# these in the $PATH, or to query by `.desktop` file, I prefer to keep
# them separate.
super + shift + d
	flatpakmenu

# Tools and utilities
# -------------------

#####PLACEHOLDER for future release of dunst
#### TODO add all `dunst` related keys here.  Currently, it only supports
#### setting key bindings inside `dunstrc`, but there is ongoing work to
#### allow an external program to handle them.  Below is an example
#### implementation in lieu of the actual commands, which assigns the key
#### chords I have specified in `dunstrc`.
###super + {_, shift + } v
###	VIEW {context menu of} last notification (shows max 3 at a time)
###super + {_, shift + } c
###	CLOSE {all} notification{s}

# Screenshots (requires `scrot`).  First one is for the focused window.
# The other is of the entire X session (including all active monitors).
# Note that `scrot` also has an interactive mode that I do not use.
Print
	scrot -u -z '%Y-%m-%d_%H:%M:%S_$wx$h$n.png' -e 'mv $f ~/Desktop' && notify-send -i gnome-screenshot "Window view screenshot" "Saved image to Desktop"
super + Print
	scrot -m -z '%Y-%m-%d_%H:%M:%S_$wx$h.png' -e 'mv $f ~/Desktop' && notify-send -i gnome-screenshot "Screen view screenshot" "Saved image to Desktop"

# Control the laptop's screen brightness (requires `xbacklight`).
XF86MonBrightness{Down,Up}
	xbacklight {-dec 15,-inc 15}

# Screen locker (requires `slock`, which in Debian is provided by the
# package `suckless-tools`).
XF86ScreenSaver
	slock

# Media controls
# --------------

# MPRIS method that manages all supporting clients or programs.  For
# MPD, you must have `mpdris2` (Debian repos) as a bridge between it and
# MPRIS.  `playerctl` is the tool that controls all MPRIS-aware
# applications.  These mappings use dedicated media keys.
XF86Audio{Play,Prev,Next,Stop}
	playerctl {play-pause,previous,next,stop}

# mpc method that is specific to the Music Player Daemon.  This uses
# dedicated media keys.
super + XF86Audio{Mute,LowerVolume,RaiseVolume}
	mpc {toggle,prev,next,stop}

# mpc method as above, but using the arrow keys.
super + {Down,Left,Right,Up}
	mpc {toggle,prev,next,stop}

# Speaker/output volume.  Requires `amixer` and dedicated keys.
XF86Audio{Mute,LowerVolume,RaiseVolume}
	amixer set Master {toggle,5%-,5%+}

# Microphone/input volume.  Same requirements as previous definition.
XF86AudioMicMute
	amixer set Capture toggle
super + XF86Audio{Mute,LowerVolume,RaiseVolume}
	amixer set Capture {toggle,5%-,5%+}

