dot

vizie's NixOS desktop: Hyprland, CachyOS kernel and gaming tweaks

85 lines2846 bytesBourne Again Shell (bash)executable
1#!/usr/bin/env bash
2# Opens/closes the Waybar flyout panels. Called by the Waybar buttons.
3# toggle.sh [control-center|notifications] toggle that panel (default: control-center)
4# toggle.sh close close whichever panel is open
5# Only one panel is open at a time. Errors are shown as a notification and written to
6# $XDG_RUNTIME_DIR/control-center.log
7
8PANEL="${1:-control-center}"
9
10# Force a monitor by number (0, 1, ...). Leave empty to open on the monitor you clicked on.
11MONITOR=""
12
13DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
14EWW=(eww --config "$DIR")
15LOG="${XDG_RUNTIME_DIR:-/tmp}/control-center.log"
16
17fail() {
18 notify-send -u critical "Control center" "$1 (log: $LOG)" 2>/dev/null
19 exit 1
20}
21
22command -v eww >/dev/null 2>&1 || fail "eww is not installed"
23
24case "$PANEL" in
25 control-center|notifications|close) ;;
26 *) fail "Unknown panel: $PANEL" ;;
27esac
28
29ACTIVE=$("${EWW[@]}" active-windows 2>/dev/null)
30is_open() { grep -q "^$1:" <<<"$ACTIVE"; }
31
32close_all() {
33 local open=()
34 for w in control-center notifications cc-closer; do
35 is_open "$w" && open+=("$w")
36 done
37 [ ${#open[@]} -gt 0 ] && "${EWW[@]}" close "${open[@]}"
38 "${EWW[@]}" update confirm=none notifs_open=false
39}
40
41# Clicking the button of the panel that is open (or asking to close) just closes it;
42# clicking the other button swaps panels.
43if [ "$PANEL" = close ] || is_open "$PANEL"; then
44 close_all
45 exit 0
46fi
47close_all
48
49# The focused monitor is the one the bar button was clicked on. Hyprland numbers monitors
50# (HDMI-A-2 = 1) but Eww uses GTK's own numbering, so translate by matching screen positions.
51# If that isn't possible we fall back to Hyprland's number, and finally to monitor 1.
52if [ -z "$MONITOR" ] && command -v hyprctl >/dev/null 2>&1; then
53 MONITOR=$(hyprctl monitors -j 2>/dev/null | GDK_BACKEND=wayland python3 -c '
54import sys, json
55mons = json.load(sys.stdin)
56cur = next((m for m in mons if m.get("focused")), mons[0])
57idx = cur["id"]
58try:
59 import gi
60 gi.require_version("Gdk", "3.0")
61 from gi.repository import Gdk
62 Gdk.init([])
63 display = Gdk.Display.get_default()
64 for i in range(display.get_n_monitors()):
65 g = display.get_monitor(i).get_geometry()
66 if (g.x, g.y) == (cur["x"], cur["y"]):
67 idx = i
68 break
69except Exception:
70 pass
71print(idx)
72' 2>/dev/null)
73fi
74MONITOR="${MONITOR:-1}"
75
76if [ "$PANEL" = notifications ]; then
77 # Fill the list before the panel appears; Eww then keeps it fresh while it is open.
78 "${EWW[@]}" update notifs="$(python3 "$DIR/scripts/notifications.py")" notifs_open=true
79fi
80
81out=$("${EWW[@]}" open-many cc-closer "$PANEL" \
82 --arg "cc-closer:monitor=$MONITOR" --arg "$PANEL:monitor=$MONITOR" 2>&1) || {
83 printf '%s\n' "$out" > "$LOG"
84 fail "Could not open the panel: $(printf '%s' "$out" | head -1)"
85}