From 2de384cff5b935d68eb7b517de7173d29fdeaa03 Mon Sep 17 00:00:00 2001 From: Marius Peter Date: Sun, 8 Jan 2023 16:32:16 +0100 Subject: Herbstluftwm autostart. --- herbstluftwm-autostart.org | 396 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 325 insertions(+), 71 deletions(-) (limited to 'herbstluftwm-autostart.org') diff --git a/herbstluftwm-autostart.org b/herbstluftwm-autostart.org index f6351d7..534dba0 100755 --- a/herbstluftwm-autostart.org +++ b/herbstluftwm-autostart.org @@ -15,9 +15,10 @@ * Introduction -This is my literate configuration for {{{hl}}}. It is a manual tiling -window manager and has the particularity of being configured via the -~herbstclient~ program. +This is my literate configuration for {{{hl}}} and other programs +started at the beginning of a graphical session. {{{hl}}} is a manual +tiling window manager and is configured via the ~herbstclient~ +program. #+begin_center \Huge\textbf{Herbstluft}\\ @@ -28,40 +29,19 @@ window manager and has the particularity of being configured via the * Early setup -** Compositor - -#+BEGIN_SRC shell - killall picom - picom & -#+END_SRC - - ** Definitions We begin by defining a shorthand name for the ~herbstclient~ program: +#+NAME: hc #+BEGIN_SRC shell hc() { herbstclient "$@" } #+END_SRC -Choice of Modkey. Mod1 is Alt, Mod4 is Super. - -#+BEGIN_SRC shell - Mod=Mod4 -#+END_SRC - - -** ~Plank~ dock - -#+BEGIN_SRC shell - killall plank - plank & -#+END_SRC - -** TODO Basic +** Basic We make {{{hl}}} execute code associated with the ~reload~ hook. @@ -84,6 +64,12 @@ We remove all existing keybindings. hc keyunbind --all #+END_SRC +Choice of Modkey. =Mod1= is =Alt=, =Mod4= is =Super=. + +#+BEGIN_SRC shell + Mod=Mod4 +#+END_SRC + ** Basic interaction with {{{hl}}} @@ -94,30 +80,35 @@ We remove all existing keybindings. #+END_SRC -** Open programs interactively +** Close focused window or remove frame #+BEGIN_SRC shell - hc keybind $Mod-d spawn dmenu_run + hc keybind $Mod-q close_or_remove #+END_SRC -** Close focused window or remove frame +** Application shortcuts + + +*** Menu + +{{{hl}}} wrapper around dmenu. #+BEGIN_SRC shell - hc keybind $Mod-q close_or_remove + hc keybind $Mod-d spawn "/etc/xdg/herbstluftwm/dmenu_run_hlwm" #+END_SRC -** Spawn a terminal +*** Terminal -We use our $TERMINAL with ~xfce4-terminal~ as fallback. +We use =st=. #+BEGIN_SRC shell - hc keybind $Mod-Return spawn "${TERMINAL:-xfce4-terminal}" + hc keybind $Mod-Return spawn "st" #+END_SRC -** Start common applications +*** TODO Emacs We assign shortcuts to commonly used applications. @@ -194,8 +185,8 @@ Resizing frames and floating clients. *** Basic definitions #+BEGIN_SRC shell - tag_names=( {1..9} ) - tag_keys=( {1..9} 0 ) + tag_names=( {1..5} ) + tag_keys=( {1..5} 0 ) hc rename default "${tag_names[0]}" || true for i in "${!tag_names[@]}" ; do @@ -242,7 +233,7 @@ layout is skipped. #+END_SRC -*** Mouse bindings +** Mouse bindings #+BEGIN_SRC shell hc mouseunbind --all @@ -252,7 +243,7 @@ layout is skipped. #+END_SRC -*** Cycle the active screens +** Cycle the active screens #+BEGIN_SRC shell hc keybind $Mod-Tab cycle_all +1 @@ -266,7 +257,7 @@ This is a ``shorter'' shortcut. #+END_SRC -*** Jump to to next urgent program +** Jump to to next urgent program Super useful when getting prompted for permissions in a browser on a different tag! @@ -278,15 +269,20 @@ different tag! * Theme - -** Basic - #+BEGIN_SRC shell hc attr theme.tiling.reset 1 hc attr theme.floating.reset 1 #+END_SRC +** Colors + +#+begin_src shell + color_main='#666611' + xsetroot -solid $color_main +#+end_src + + ** Frames #+BEGIN_SRC shell @@ -383,7 +379,6 @@ window and the frame may be omitted. hc set smart_window_surroundings off #+END_SRC - #+BEGIN_SRC shell hc set mouse_recenter_gap 0 #+END_SRC @@ -417,45 +412,304 @@ First, we cancel all previously bound rules. #+END_SRC -** Multi-monitor setup - -#+BEGIN_SRC shell - # do multi monitor setup here, e.g.: - # hc set_monitors 1280x1024+0+0 1280x1024+1280+0 - # or simply: - # hc detect_monitors -#+END_SRC +* Other programs ** Panel -So nice. +#+begin_src shell + xset +fp /home/blendux/.fonts/ + kill $(pgrep --full "panel.sh") + bash ~/.config/herbstluftwm/panel.sh +#+end_src + +This panel is adapted from the one provided by default by {{{hl}}}, +located at [[file:/etc/xdg/herbstluftwm/panel.sh]]. + +I'm using =lemonbar-xft=, which provides XFT support. + +#+begin_src shell :tangle no + font='-*-hack-medium-r-*-*-*-*-*-*-*-*-*-*' + font_xft='Hack' + # extract colors from hlwm and omit alpha-value + bgcolor=$(herbstclient get frame_border_normal_color|sed 's,^\(\#[0-9a-f]\{6\}\)[0-9a-f]\{2\}$,\1,') + selbg=$(herbstclient get window_border_active_color|sed 's,^\(\#[0-9a-f]\{6\}\)[0-9a-f]\{2\}$,\1,') + selfg='#101010' + + # Quick maffs + monitor_width=$(herbstclient monitor_rect 0 | awk '{ print $3 }') + monitor_height=$(herbstclient monitor_rect 0 | awk '{ print $4 }') + window_gap=$(herbstclient get window_gap) + let "bar_width = monitor_width - (2 * $window_gap)" + bar_height=42 + offset_horizontal=$window_gap + offset_vertical=0 + bar_dimensions=${bar_width}x${bar_height}+${offset_horizontal}+${offset_vertical} + + + hlwm_datetime_short () { + date +"%R | %F" + } + hlwm_datetime_long () { + date +"%A, %d %B %Y | %R" + } -** TODO Vanilla shell panel -# Add panel in here, literally + hlwm_battery_status () { + acpi | awk -F', ' '{ print $3 }' + } -#+BEGIN_SRC shell + hlwm_battery_level () { + acpi | awk -F', ' '{ print $2 }' + } -#+END_SRC + (while true; do + echo "%{c}$(hlwm_datetime_short)%{r}$(hlwm_battery_status) $(hlwm_battery_level)" + sleep 1 + done + ) | lemonbar -f ${font_xft} -g $bar_dimensions # -B $selbg +#+end_src -#+BEGIN_SRC shell - panel=~/.config/herbstluftwm/panel.sh - [ -x "$panel" ] || panel=/etc/xdg/herbstluftwm/panel.sh - for monitor in $(hc list_monitors | cut -d: -f1) ; do - # start it on each monitor - "$panel" "$monitor" & - done -#+END_SRC +#+RESULTS: +#+begin_src shell :tangle "~/.config/herbstluftwm/panel.sh" + quote() { + local q="$(printf '%q ' "$@")" + printf '%s' "${q% }" + } -** COMMENT Xmobar + if [[ -f /usr/lib/bash/sleep ]]; then + # load and enable 'sleep' builtin (does not support unit suffixes: h, m, s!) + # requires pkg 'bash-builtins' on debian; included in 'bash' on arch. + enable -f /usr/lib/bash/sleep sleep + fi + + hc_quoted="$(quote "${herbstclient_command[@]:-herbstclient}")" + hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} + monitor=${1:-0} + geometry=( $(hc monitor_rect "$monitor") ) + if [ -z "$geometry" ] ;then + echo "Invalid monitor $monitor" + exit 1 + fi + # geometry has the format W H X Y + x=${geometry[0]} + y=${geometry[1]} + panel_width=${geometry[2]} + panel_height=32 + # font="-*-fixed-medium-*-*-*-24-*-*-*-*-*-*-*" + font='-*-hack-medium-r-*-*-*-*-*-*-*-*-*-*' + # font='Hack:pixelsize=20' + # extract colors from hlwm and omit alpha-value + bgcolor=$(hc get frame_border_normal_color|sed 's,^\(\#[0-9a-f]\{6\}\)[0-9a-f]\{2\}$,\1,') + selbg=$(hc get window_border_active_color|sed 's,^\(\#[0-9a-f]\{6\}\)[0-9a-f]\{2\}$,\1,') + selfg='#101010' + + #### + # Try to find textwidth binary. + # In e.g. Ubuntu, this is named dzen2-textwidth. + if which textwidth &> /dev/null ; then + textwidth="textwidth"; + elif which dzen2-textwidth &> /dev/null ; then + textwidth="dzen2-textwidth"; + elif which xftwidth &> /dev/null ; then # For guix + textwidth="xftwidth"; + else + echo "This script requires the textwidth tool of the dzen2 project." + exit 1 + fi + #### + # true if we are using the svn version of dzen2 + # depending on version/distribution, this seems to have version strings like + # "dzen-" or "dzen-x.x.x-svn" + if dzen2 -v 2>&1 | head -n 1 | grep -q '^dzen-\([^,]*-svn\|\),'; then + dzen2_svn="true" + else + dzen2_svn="" + fi + + if awk -Wv 2>/dev/null | head -1 | grep -q '^mawk'; then + # mawk needs "-W interactive" to line-buffer stdout correctly + # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=593504 + uniq_linebuffered() { + awk -W interactive '$0 != l { print ; l=$0 ; fflush(); }' "$@" + } + else + # other awk versions (e.g. gawk) issue a warning with "-W interactive", so + # we don't want to use it there. + uniq_linebuffered() { + awk '$0 != l { print ; l=$0 ; fflush(); }' "$@" + } + fi + + hc pad $monitor $panel_height + + { + ### Event generator ### + # based on different input data (mpc, date, hlwm hooks, ...) this generates events, formed like this: + # \t [...] + # e.g. + # date ^fg(#efefef)18:33^fg(#909090), 2013-10-^fg(#efefef)29 + + #mpc idleloop player & + while true ; do + # output is checked once a second, but a "date" event is only + # generated if the output changed compared to the previous run. + printf 'date\t^fg(#efefef)%(%H:%M)T^fg(#909090), %(%Y-%m)T-^fg(#efefef)%(%d)T\n' + sleep 1 || break + done > >(uniq_linebuffered) & + childpid=$! + hc --idle + kill $childpid + } 2> /dev/null | { + IFS=$'\t' read -ra tags <<< "$(hc tag_status $monitor)" + visible=true + date="" + windowtitle="" + while true ; do + + ### Output ### + # This part prints dzen data based on the _previous_ data handling run, + # and then waits for the next event to happen. + + separator="^bg()^fg($selbg)|" + # draw tags + for i in "${tags[@]}" ; do + case ${i:0:1} in + '#') + echo -n "^bg($selbg)^fg($selfg)" + ;; + '+') + echo -n "^bg(#9CA668)^fg(#141414)" + ;; + ':') + echo -n "^bg()^fg(#ffffff)" + ;; + '!') + echo -n "^bg(#FF0675)^fg(#141414)" + ;; + ,*) + echo -n "^bg()^fg(#ababab)" + ;; + esac + if [ ! -z "$dzen2_svn" ] ; then + # clickable tags if using SVN dzen + echo -n "^ca(1,$hc_quoted focus_monitor \"$monitor\" && " + echo -n "$hc_quoted use \"${i:1}\") ${i:1} ^ca()" + else + # non-clickable tags if using older dzen + echo -n " ${i:1} " + fi + done + echo -n "$separator" + echo -n "^bg()^fg() ${windowtitle//^/^^}" + # small adjustments + right="$separator^bg() $date $separator" + right_text_only=$(echo -n "$right" | sed 's.\^[^(]*([^)]*)..g') + # get width of right aligned text.. and add some space.. + width=$($textwidth "$font" "$right_text_only ") + echo -n "^pa($(($panel_width - $width)))$right" + echo + + ### Data handling ### + # This part handles the events generated in the event loop, and sets + # internal variables based on them. The event and its arguments are + # read into the array cmd, then action is taken depending on the event + # name. + # "Special" events (quit_panel/togglehidepanel/reload) are also handled + # here. + + # wait for next event + IFS=$'\t' read -ra cmd || break + # find out event origin + case "${cmd[0]}" in + tag*) + #echo "resetting tags" >&2 + IFS=$'\t' read -ra tags <<< "$(hc tag_status $monitor)" + ;; + date) + #echo "resetting date" >&2 + date="${cmd[@]:1}" + ;; + quit_panel) + exit + ;; + togglehidepanel) + currentmonidx=$(hc list_monitors | sed -n '/\[FOCUS\]$/s/:.*//p') + if [ "${cmd[1]}" -ne "$monitor" ] ; then + continue + fi + if [ "${cmd[1]}" = "current" ] && [ "$currentmonidx" -ne "$monitor" ] ; then + continue + fi + echo "^togglehide()" + if $visible ; then + visible=false + hc pad $monitor 0 + else + visible=true + hc pad $monitor $panel_height + fi + ;; + reload) + exit + ;; + focus_changed|window_title_changed) + windowtitle="${cmd[@]:2}" + ;; + #player) + # ;; + esac + done + + ### dzen2 ### + # After the data is gathered and processed, the output of the previous block + # gets piped to dzen2. + + } | dzen2 -w $panel_width -x $x -y $y -fn "$font" -h $panel_height \ + -e "button3=;button4=exec:$hc_quoted use_index -1;button5=exec:$hc_quoted use_index +1" \ + -ta l -bg "$bgcolor" -fg '#efefef' +#+end_src + + +** Dock + +#+BEGIN_SRC shell + if [ $(pgrep plank) ] + then + pkill plank + else + plank & + fi +#+END_SRC + + +** System information + +#+begin_src shell + if [ $(pgrep conky) ] + then + pkill conky + else + conky & + fi +#+end_src -#+BEGIN_SRC shell - killall xmobar - for monitor in $(hc list_monitors | cut -d: -f1) ; do - # start it on each monitor - xmobar & - done +** Compositor + +#+BEGIN_SRC shell + if [ $(pgrep picom) ] + then + pkill picom + else + picom & + fi #+END_SRC + + +** TODO Desktop Background + +#+begin_src shell + ~/.fehbg & +#+end_src -- cgit v1.2.3