#!/usr/bin/env bash # a i3-like scratchpad for arbitrary applications. # # this lets a new monitor called "scratchpad" appear in from the top into the # current monitor. There the "scratchpad" will be shown (it will be created if # it doesn't exist yet). If the monitor already exists it is scrolled out of # the screen and removed again. # # Warning: this uses much resources because herbstclient is forked for each # animation step. # # If a tag name is supplied, this is used instead of the scratchpad tag="${1:-scratchpad}" hc() { "${herbstclient_command[@]:-herbstclient}" "$@" ;} #scratchpad=(alacritty --title "$tag" --class "scratchpad") scratchpad=(urxvt -title "$tag" -name "scratchpad") #scratchpad=(xterm -title "$tag" -name "scratchpad") read -r -a mrect < <(hc monitor_rect "") monitor_w=${mrect[2]} monitor_h=${mrect[3]} monitor_w_offset=${mrect[0]} monitor_h_offset=${mrect[1]} scratchpad_scale_factor=0.75 scratch_w=$(printf "%d" "$(bc -l <<< "$monitor_w * $scratchpad_scale_factor")") scratch_h=$(printf "%d" "$(bc -l <<< "$monitor_h * $scratchpad_scale_factor")") scratch_w_offset=$(((monitor_w-scratch_w)/2)) scratch_h_offset=$(((monitor_h-scratch_h)/2)) rect=( "$scratch_w" "$scratch_h" $((monitor_w_offset+scratch_w_offset)) $((monitor_h_offset+scratch_h_offset)) ) hc add "$tag" monitor=scratchpad exists=false if ! hc add_monitor "$(printf "%dx%d%+d%+d" "${rect[@]}")" \ "$tag" "$monitor" 2> /dev/null ; then exists=true else # remember which monitor was focused previously hc chain \ , new_attr string monitors.by-name."$monitor".my_prev_focus \ , substitute M monitors.focus.index \ set_attr monitors.by-name."$monitor".my_prev_focus M fi show() { [ "$(hc attr tags.by-name."$tag".client_count)" = "0" ] && hc spawn "${scratchpad[@]}" hc lock hc raise_monitor "$monitor" hc focus_monitor "$monitor" hc unlock hc lock_tag "$monitor" } hide() { # if q3terminal still is focused, then focus the previously focused monitor # (that mon which was focused when starting q3terminal) hc substitute M monitors.by-name."$monitor".my_prev_focus \ and + compare monitors.focus.name = "$monitor" \ + focus_monitor M hc remove_monitor "$monitor" } # shellcheck disable=SC2015 [ $exists = true ] && hide || show