h3rbinal.sh 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #!/usr/bin/env bash
  2. # a q3-like (or yakuake-like) terminal for arbitrary applications.
  3. #
  4. # this lets a new monitor called "q3terminal" scroll in from the top into the
  5. # current monitor. There the "scratchpad" will be shown (it will be created if
  6. # it doesn't exist yet). If the monitor already exists it is scrolled out of
  7. # the screen and removed again.
  8. #
  9. # Warning: this uses much resources because herbstclient is forked for each
  10. # animation step.
  11. #
  12. # If a tag name is supplied, this is used instead of the scratchpad
  13. tag="${1:-scratchpad}"
  14. hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;}
  15. termwidth_percent=${WIDTH_PERC:-100}
  16. mrect=( $(hc monitor_rect -p "" ) )
  17. termwidth=$(( (${mrect[2]} * termwidth_percent) / 100 ))
  18. termheight=${HEIGHT_PIXELS:-760}
  19. #termheight=${HEIGHT_PIXELS:-790}
  20. rect=(
  21. $termwidth
  22. $termheight
  23. $(( ${mrect[0]} + (${mrect[2]} - termwidth) / 2 ))
  24. $(( ${mrect[1]} - termheight ))
  25. )
  26. y_line=${mrect[1]}
  27. hc chain , add "$tag" , set_attr tags.by-name."$tag".at_end true
  28. monitor=q3terminal
  29. exists=false
  30. if ! hc add_monitor $(printf "%dx%d%+d%+d" "${rect[@]}") \
  31. "$tag" $monitor 2> /dev/null ; then
  32. exists=true
  33. else
  34. # remember which monitor was focused previously
  35. hc chain \
  36. , new_attr string monitors.by-name."$monitor".my_prev_focus \
  37. , substitute M monitors.focus.index \
  38. set_attr monitors.by-name."$monitor".my_prev_focus M
  39. fi
  40. update_geom() {
  41. local geom=$(printf "%dx%d%+d%+d" "${rect[@]}")
  42. hc move_monitor "$monitor" $geom
  43. }
  44. steps=${ANIMATION_STEPS:-5}
  45. interval=${ANIMATION_INTERVAL:-0.01}
  46. animate() {
  47. progress=( "$@" )
  48. for i in "${progress[@]}" ; do
  49. rect[3]=$((y_line - (i * termheight) / steps))
  50. update_geom
  51. sleep "$interval"
  52. done
  53. }
  54. show() {
  55. hc lock
  56. hc raise_monitor "$monitor"
  57. hc focus_monitor "$monitor"
  58. hc unlock
  59. hc lock_tag "$monitor"
  60. animate $(seq $steps -1 0)
  61. }
  62. hide() {
  63. rect=( $(hc monitor_rect "$monitor" ) )
  64. local tmp=${rect[0]}
  65. rect[0]=${rect[2]}
  66. rect[2]=${tmp}
  67. local tmp=${rect[1]}
  68. rect[1]=${rect[3]}
  69. rect[3]=${tmp}
  70. termheight=${rect[1]}
  71. y_line=${rect[3]} # height of the upper screen border
  72. animate $(seq 0 +1 $steps)
  73. # if q3terminal still is focused, then focus the previously focused monitor
  74. # (that mon which was focused when starting q3terminal)
  75. hc substitute M monitors.by-name."$monitor".my_prev_focus \
  76. and + compare monitors.focus.name = "$monitor" \
  77. + focus_monitor M
  78. hc remove_monitor "$monitor"
  79. }
  80. [ $exists = true ] && hide || show