blob: d44249d715985dc86cc010bb41b9e0051599099b (
plain) (
blame)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
#!/usr/bin/env bash
# ==================================================
# KoolDots (2026)
# Project URL: https://github.com/LinuxBeginnings
# License: GNU GPLv3
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
# Toggle or incrementally adjust active window opacity with desktop notifications.
# Supports cycling preset levels (100% -> 85% -> 70% -> 50% -> 100%),
# stepping up/down (--inc / --dec), or setting explicit values.
# Uses flock to prevent double-execution from dual-config (.conf + .lua) loading.
set -uo pipefail
LOCK="/tmp/.hypr_toggle_opacity_${HYPRLAND_INSTANCE_SIGNATURE:-default}.lock"
STEP=0.05
MIN_OPACITY=0.20
MAX_OPACITY=1.00
config_home="${XDG_CONFIG_HOME:-$HOME/.config}"
hypr_dir="$config_home/hypr"
lua_entry="$hypr_dir/hyprland.lua"
legacy_lua_entry="$config_home/hyprland.lua"
if [[ -f "$lua_entry" || -f "$legacy_lua_entry" ]]; then
hypr_config_mode="lua"
else
hypr_config_mode="conf"
fi
icons_dir="$config_home/swaync/icons"
images_dir="$config_home/swaync/images"
if [[ -f "$icons_dir/palette.png" ]]; then
ICON="$icons_dir/palette.png"
elif [[ -f "$icons_dir/dropper.png" ]]; then
ICON="$icons_dir/dropper.png"
elif [[ -f "$images_dir/note.png" ]]; then
ICON="$images_dir/note.png"
else
ICON="$images_dir/ja.png"
fi
(
flock -n 200 || exit 0
# Get active window info
ACTIVE_JSON=$(hyprctl activewindow -j 2>/dev/null || true)
ACTIVE_CLASS=""
if [[ -n "$ACTIVE_JSON" ]]; then
ACTIVE_CLASS=$(echo "$ACTIVE_JSON" | jq -r '.class // empty' 2>/dev/null || true)
fi
CURRENT_PROP=$(hyprctl getprop active opacity 2>/dev/null || true)
CURRENT_OPAQUE=$(hyprctl getprop active opaque 2>/dev/null || true)
CURRENT_VAL=""
if [[ -n "$CURRENT_PROP" && "$CURRENT_PROP" != *"not found"* && "$CURRENT_PROP" != *"unknown"* ]]; then
CURRENT_VAL=$(echo "$CURRENT_PROP" | awk '{v = $1; if (v ~ /^[0-9.]+$/) print v;}')
fi
if [[ -z "$CURRENT_VAL" ]]; then
CURRENT_VAL=$(hyprctl -j getoption decoration:active_opacity 2>/dev/null | jq -r '.float // empty')
fi
if [[ -z "$CURRENT_VAL" || "$CURRENT_VAL" == "null" ]]; then
CURRENT_VAL=$(hyprctl getoption decoration:active_opacity 2>/dev/null | awk 'NR==1{print $2}')
fi
# Fallback to 1.0 if detection was empty
CURRENT_NUM=$(awk -v c="${CURRENT_VAL:-1.0}" 'BEGIN { v = c + 0; if (v <= 0 || v > 1.0) v = 1.0; printf "%.2f", v }')
# If window is explicitly opaque property true, consider it 1.0
if [[ "${CURRENT_OPAQUE:-false}" == "true" ]]; then
CURRENT_NUM="1.00"
fi
ACTION="${1:---toggle}"
case "$ACTION" in
--inc|+|-inc|inc|up|--up)
TARGET_NUM=$(awk -v c="$CURRENT_NUM" -v s="$STEP" -v max="$MAX_OPACITY" 'BEGIN {
v = c + s;
if (v > max) v = max;
printf "%.2f", v;
}')
;;
--dec|-|-dec|dec|down|--down)
TARGET_NUM=$(awk -v c="$CURRENT_NUM" -v s="$STEP" -v min="$MIN_OPACITY" 'BEGIN {
v = c - s;
if (v < min) v = min;
printf "%.2f", v;
}')
;;
--toggle|toggle|"")
# Cycle through predefined incremental levels: 1.00 -> 0.85 -> 0.70 -> 0.50 -> 1.00
TARGET_NUM=$(awk -v c="$CURRENT_NUM" 'BEGIN {
if (c >= 0.98) printf "0.85";
else if (c >= 0.80) printf "0.70";
else if (c >= 0.65) printf "0.50";
else printf "1.00";
}')
;;
*)
# Parse explicit number / percentage, e.g. 0.85 or 85 or 85%
RAW_ARG="${ACTION#--}"
RAW_ARG="${RAW_ARG%\%}"
TARGET_NUM=$(awk -v a="$RAW_ARG" -v min="$MIN_OPACITY" -v max="$MAX_OPACITY" 'BEGIN {
v = a + 0;
if (v > 1.0) v = v / 100.0;
if (v > max) v = max;
if (v < min) v = min;
printf "%.2f", v;
}')
;;
esac
TARGET_PROP="${TARGET_NUM} ${TARGET_NUM}"
PERCENT=$(awk -v v="$TARGET_NUM" 'BEGIN { printf "%d", (v * 100) + 0.5 }')
if [ "$PERCENT" -ge 99 ]; then
OPAQUE_ACTION="true"
DISPLAY_MSG="100% (Opaque)"
else
OPAQUE_ACTION="false"
DISPLAY_MSG="${PERCENT}%"
fi
if [[ "$hypr_config_mode" == "lua" ]]; then
# Set window-level property so it affects the active window even when windowrules are active
hyprctl eval "return hl.dispatch(hl.dsp.window.set_prop({ prop = 'opacity', value = '${TARGET_PROP}' }))" >/dev/null 2>&1 || true
hyprctl eval "return hl.dispatch(hl.dsp.window.set_prop({ prop = 'opaque', value = '${OPAQUE_ACTION}' }))" >/dev/null 2>&1 || true
# Also update global active_opacity config
hyprctl eval "hl.config({ decoration = { active_opacity = ${TARGET_NUM} } })" >/dev/null 2>&1 || true
else
hyprctl dispatch setprop active opacity "$TARGET_PROP" >/dev/null 2>&1 || true
hyprctl dispatch setprop active opaque "$OPAQUE_ACTION" >/dev/null 2>&1 || true
hyprctl keyword decoration:active_opacity "$TARGET_NUM" >/dev/null 2>&1 || true
fi
# Send notification
if command -v notify-send >/dev/null 2>&1 && [[ -n "${WAYLAND_DISPLAY:-}${DISPLAY:-}" ]]; then
SUBTITLE="${ACTIVE_CLASS:-Active Window}"
notify-send -e \
-h string:x-canonical-private-synchronous:opacity_notif \
-h int:value:"$PERCENT" \
-u low \
-i "$ICON" \
" Opacity: ${DISPLAY_MSG}" " ${SUBTITLE}" 2>/dev/null || true
fi
) 200>"$LOCK"
|