From f4439fb9bb24edbb75437a31600dc5080207a1c3 Mon Sep 17 00:00:00 2001
From: Patrick Spek
Date: Mon, 8 Mar 2021 13:00:29 +0100
Subject: Update hlwm config
---
.config/herbstluftwm/autostart | 61 ++++++------
.config/herbstluftwm/panel-bot.sh | 84 +++++++++++++++++
.config/herbstluftwm/panel-top.sh | 188 +++++++++++++++++++++++++++++++++++++
.config/herbstluftwm/panel.sh | 189 --------------------------------------
4 files changed, 300 insertions(+), 222 deletions(-)
create mode 100755 .config/herbstluftwm/panel-bot.sh
create mode 100755 .config/herbstluftwm/panel-top.sh
delete mode 100755 .config/herbstluftwm/panel.sh
(limited to '.config')
diff --git a/.config/herbstluftwm/autostart b/.config/herbstluftwm/autostart
index d59b4a3..69c6d40 100755
--- a/.config/herbstluftwm/autostart
+++ b/.config/herbstluftwm/autostart
@@ -8,37 +8,26 @@ hc() {
hc emit_hook reload
-xsetroot -solid '#5A8E3A'
+xsetroot -solid '#cccccc'
# remove all existing keybindings
hc keyunbind --all
# keybindings
-# if you have a super key you will be much happier with Mod set to Mod4
-#Mod=Mod1 # Use alt as the main modifier
Mod=Mod4 # Use the super key as the main modifier
hc keybind $Mod-Shift-x quit
-hc keybind $Mod-r reload
-hc keybind $Mod-x close
-#hc keybind $Mod-Return spawn "${TERMINAL:-xterm}" # use your $TERMINAL with xterm as fallback
+hc keybind $Mod-r reload
+hc keybind $Mod-x close
# basic movement in tiling and floating mode
# focusing clients
-hc keybind $Mod-Left focus left
-hc keybind $Mod-Down focus down
-hc keybind $Mod-Up focus up
-hc keybind $Mod-Right focus right
hc keybind $Mod-h focus left
hc keybind $Mod-j focus down
hc keybind $Mod-k focus up
hc keybind $Mod-l focus right
# moving clients in tiling and floating mode
-hc keybind $Mod-Shift-Left shift left
-hc keybind $Mod-Shift-Down shift down
-hc keybind $Mod-Shift-Up shift up
-hc keybind $Mod-Shift-Right shift right
hc keybind $Mod-Shift-h shift left
hc keybind $Mod-Shift-j shift down
hc keybind $Mod-Shift-k shift up
@@ -46,8 +35,8 @@ hc keybind $Mod-Shift-l shift right
# splitting frames
# create an empty frame at the specified direction
-hc keybind $Mod-\\ split bottom 0.5
-hc keybind $Mod-\| split right 0.5
+hc keybind $Mod-backslash split bottom 0.5
+hc keybind $Mod-Shift-backslash split right 0.5
# let the current frame explode into subframes
hc keybind $Mod-Control-space split explode
@@ -57,10 +46,6 @@ hc keybind $Mod-Control-h resize left +$resizestep
hc keybind $Mod-Control-j resize down +$resizestep
hc keybind $Mod-Control-k resize up +$resizestep
hc keybind $Mod-Control-l resize right +$resizestep
-hc keybind $Mod-Control-Left resize left +$resizestep
-hc keybind $Mod-Control-Down resize down +$resizestep
-hc keybind $Mod-Control-Up resize up +$resizestep
-hc keybind $Mod-Control-Right resize right +$resizestep
# tags
tag_names=( work social web mail fun media vms 8 9 )
@@ -101,7 +86,8 @@ hc mousebind $Mod-Button2 zoom
hc mousebind $Mod-Button3 resize
# focus
-hc keybind $Mod-BackSpace cycle_monitor
+hc keybind $Mod-Control+j cycle_monitor -1
+hc keybind $Mod-Control+k cycle_monitor +1
hc keybind $Mod-Tab cycle_all +1
hc keybind $Mod-Shift-Tab cycle_all -1
hc keybind $Mod-c cycle
@@ -113,18 +99,20 @@ hc attr theme.floating.reset 1
hc set frame_border_active_color '#3381DA'
hc set frame_border_normal_color '#222222'
hc set frame_bg_normal_color '#777777'
-hc set frame_bg_active_color '#3381DA'
+hc set frame_bg_active_color '#000000'
hc set frame_border_width 1
hc set always_show_frame on
-hc set frame_bg_transparent on
-hc set frame_transparent_width 5
+hc set frame_bg_transparent 1
+hc set frame_normal_opacity 0
+hc set frame_focus_opacity 1
+#hc set frame_transparent_width 5
hc set frame_gap 4
-hc attr theme.active.color '#9fbc00'
+hc attr theme.active.color '#3381DA'
hc attr theme.normal.color '#454545'
hc attr theme.urgent.color orange
hc attr theme.inner_width 1
-hc attr theme.inner_color black
+#hc attr theme.inner_color black
hc attr theme.border_width 3
hc attr theme.floating.border_width 4
hc attr theme.floating.outer_width 1
@@ -133,7 +121,7 @@ hc attr theme.active.inner_color '#3E4A00'
hc attr theme.active.outer_color '#3E4A00'
hc attr theme.background_color '#141414'
-hc set window_gap 0
+hc set window_gap 4
hc set frame_padding 0
hc set smart_window_surroundings off
hc set smart_frame_surroundings on
@@ -159,12 +147,19 @@ hc unlock
# do multi monitor setup here, e.g.:
# hc set_monitors 1280x1024+0+0 1280x1024+1280+0
# or simply:
-# hc detect_monitors
+hc detect_monitors
+
+# find the top panel
+panel_top=~/.config/herbstluftwm/panel-top.sh
+[ -x "$panel_top" ] || panel_top=/etc/xdg/herbstluftwm/panel.sh
+
+panel_bot=~/.config/herbstluftwm/panel-bot.sh
-# find the panel
-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" &
+ # Create space for the panels to exist
+ hc pad "$monitor" 21 0 21 0
+
+ # Start panels
+ "$panel_top" "$monitor" &
+ "$panel_bot" "$monitor" &
done
diff --git a/.config/herbstluftwm/panel-bot.sh b/.config/herbstluftwm/panel-bot.sh
new file mode 100755
index 0000000..4a3bc18
--- /dev/null
+++ b/.config/herbstluftwm/panel-bot.sh
@@ -0,0 +1,84 @@
+#!/usr/bin/env bash
+
+hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ; }
+quote() { local q="$(printf '%q ' "$@")"; printf '%s' "${q% }" ; }
+uniq_linebuffered() { awk '$0 != l { print ; l=$0 ; fflush(); }' "$@"; }
+
+monitor=${1:-0}
+
+hc attr "monitors.$monitor" > /dev/null || { printf "Invalid monitor $monitor" && exit 1 ; }
+
+monitor_tag="$(herbstclient attr "monitors.$monitor.tag")"
+monitor_offset_x=$(hc monitor_rect "$monitor" | awk '{print $1 }')
+monitor_offset_y=$(hc monitor_rect "$monitor" | awk '{print $2 }')
+monitor_width=$(hc monitor_rect "$monitor" | awk '{ print $3 }')
+monitor_height=$(hc monitor_rect "$monitor" | awk '{ print $4 }')
+panel_height=21
+panel_color_bg="$(hc get frame_border_normal_color)"
+panel_color_fg="#efefef"
+panel_color_focus="$(hc get frame_border_active_color)"
+panel_font="Liberation Mono:size=9"
+panel_offset_x=$(( monitor_offset_x ))
+panel_offset_y=$(( monitor_offset_y + monitor_height - panel_height ))
+
+{
+ hc --idle
+} 2> /dev/null | {
+ while :
+ do
+ # Wait for an event
+ IFS=$'\t' read -ra event || break
+
+ # Declare clients as an array
+ declare -a clients
+
+ # Collect all clients on the monitor
+ for client in $(hc attr clients | grep '0x')
+ do
+ [[ "$(hc attr "clients.$client.tag")" != $monitor_tag ]] && continue
+
+ clients+=("$client")
+ done
+
+ name_offset_interval=$(( monitor_width / ${#clients[@]} ))
+
+ # Look up current focus window
+ focus="$(hc attr clients.focus.winid)"
+
+ # Loop through the clients to create a representation
+ index=0
+
+ for client in "${clients[@]}"
+ do
+
+ if [[ "$client" == "$focus." ]]
+ then
+ color_fg="$panel_color_focus"
+ else
+ color_fg="$panel_color_fg"
+ fi
+
+ name=" $(hc attr "clients.$client.title") "
+ name_width=$(xftwidth "$panel_font" "$name")
+ name_offset=$(( name_offset_interval * index ))
+
+ printf "^pa(%s)^bg(%s)^fg(%s)^ca(1,%s)%s^ca()" \
+ "$name_offset" \
+ "$panel_color_bg" \
+ "$color_fg" \
+ "herbstclient jumpto '$client'" \
+ "$name"
+
+ index=$(( index + 1 ))
+ done
+
+ # Add a newline
+ printf "\n"
+
+ # Clean up some variables
+ unset clients
+ unset index
+ done
+} | dzen2 -w "$monitor_width" -x "$panel_offset_x" -y "$panel_offset_y" -fn "$panel_font" -h "$panel_height" \
+ -e "button3=;button4=exec:$hc_quoted use_index -1;button5=exec:$hc_quoted use_index +1" \
+ -ta l -bg "$panel_color_bg" -fg "$panel_color_fg"
diff --git a/.config/herbstluftwm/panel-top.sh b/.config/herbstluftwm/panel-top.sh
new file mode 100755
index 0000000..536f674
--- /dev/null
+++ b/.config/herbstluftwm/panel-top.sh
@@ -0,0 +1,188 @@
+#!/usr/bin/env bash
+
+quote() {
+ local q="$(printf '%q ' "$@")"
+ printf '%s' "${q% }"
+}
+
+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=21
+font="Liberation Mono:size=9"
+bgcolor=$(hc get frame_border_normal_color)
+selbg=$(hc get window_border_active_color)
+selfg='#101010'
+
+####
+# Try to find textwidth binary.
+# In e.g. Ubuntu, this is named dzen2-textwidth.
+if which xftwidth > /dev/null
+then
+ textwidth=xftwidth
+elif which textwidth > /dev/null
+then
+ textwidth="textwidth";
+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
+
+{
+ ### 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
+ # "date" output is checked once a second, but an event is only
+ # generated if the output changed compared to the previous run.
+ date +$'date\t^fg(#efefef)%H:%M^fg(#909090), %Y-%m-^fg(#efefef)%d'
+ 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'
diff --git a/.config/herbstluftwm/panel.sh b/.config/herbstluftwm/panel.sh
deleted file mode 100755
index 5b1deb0..0000000
--- a/.config/herbstluftwm/panel.sh
+++ /dev/null
@@ -1,189 +0,0 @@
-#!/usr/bin/env bash
-
-quote() {
- local q="$(printf '%q ' "$@")"
- printf '%s' "${q% }"
-}
-
-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=16
-font="-*-fixed-medium-*-*-*-12-*-*-*-*-*-*-*"
-bgcolor=$(hc get frame_border_normal_color)
-selbg=$(hc get window_border_active_color)
-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="xtfwidth";
-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
- # "date" output is checked once a second, but an event is only
- # generated if the output changed compared to the previous run.
- date +$'date\t^fg(#efefef)%H:%M^fg(#909090), %Y-%m-^fg(#efefef)%d'
- 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.
-
-} 2> /dev/null | 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'
--
cgit v1.1