aboutsummaryrefslogtreecommitdiffstats
path: root/herbstluftwm/.local/bin/scratchpad.sh
blob: 3e550e45f9b0fadba90620c2c55e8b6b4ce2b1a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/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