From b76e27d4665187f15cb12a980051ab17222a08fd Mon Sep 17 00:00:00 2001 From: antistereov Date: Sat, 28 Mar 2026 19:50:28 +0100 Subject: [PATCH] feat(waybar): add autohide dock --- waybar/config-dock.jsonc | 26 +++++++ waybar/scripts/dock-autohide.sh | 130 ++++++++++++++++++++++++++++++++ waybar/scripts/dock-toggle.sh | 111 +++++++++++++++++++++++++++ waybar/style-dock.css | 8 ++ 4 files changed, 275 insertions(+) create mode 100644 waybar/config-dock.jsonc create mode 100755 waybar/scripts/dock-autohide.sh create mode 100755 waybar/scripts/dock-toggle.sh create mode 100644 waybar/style-dock.css diff --git a/waybar/config-dock.jsonc b/waybar/config-dock.jsonc new file mode 100644 index 0000000..caabb33 --- /dev/null +++ b/waybar/config-dock.jsonc @@ -0,0 +1,26 @@ +{ + "layer": "overlay", + "position": "bottom", + "exclusive": false, + "passthrough": false, + "height": 56, + "margin-top": 0, + "margin-bottom": 8, + "margin-left": 0, + "margin-right": 0, + "modules-left": [], + "modules-center": [ + "custom/launcher", + "hyprland/workspaces" + ], + "modules-right": [], + "custom/launcher": { + "format": "", + "on-click": "wofi --show drun" + }, + "hyprland/workspaces": { + "format": "{icon}", + "on-click": "activate", + "sort-by-number": true + } +} diff --git a/waybar/scripts/dock-autohide.sh b/waybar/scripts/dock-autohide.sh new file mode 100755 index 0000000..4fe9af8 --- /dev/null +++ b/waybar/scripts/dock-autohide.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash + +set -euo pipefail + +TOGGLE="$HOME/.config/waybar/scripts/dock-toggle.sh" + +SHOW_EDGE_SIZE=12 +DOCK_HEIGHT=72 +HIDE_DELAY=0.35 +POLL_INTERVAL=0.08 + +LOG_FILE="/tmp/waybar-dock.log" +DEBUG=1 + +last_inside_dock_time=0 + +log() { + if [[ "$DEBUG" -eq 1 ]]; then + echo "[$(date '+%H:%M:%S.%3N')] $*" >>"$LOG_FILE" + fi +} + +get_cursor() { + hyprctl -j cursorpos +} + +get_monitors() { + hyprctl -j monitors +} + +get_monitor_for_cursor() { + local cursor_json monitors_json + cursor_json="$(get_cursor)" + monitors_json="$(get_monitors)" + + local cx cy + cx="$(jq -r '.x' <<<"$cursor_json")" + cy="$(jq -r '.y' <<<"$cursor_json")" + + jq -c --argjson cx "$cx" --argjson cy "$cy" ' + map( + . as $m + | ($m.width / $m.scale) as $lw + | ($m.height / $m.scale) as $lh + | select( + ($cx >= $m.x) and + ($cx < ($m.x + $lw)) and + ($cy >= $m.y) and + ($cy < ($m.y + $lh)) + ) + ) | first + ' <<<"$monitors_json" +} + +dock_visible() { + [[ "$("$TOGGLE" status)" == "visible" ]] +} + +show_dock() { + "$TOGGLE" show +} + +hide_dock() { + "$TOGGLE" hide +} + +log "Started dock autohide" + +while true; do + cursor_json="$(get_cursor)" + monitor_json="$(get_monitor_for_cursor)" + now="$(date +%s.%N)" + + cx="$(jq -r '.x' <<<"$cursor_json")" + cy="$(jq -r '.y' <<<"$cursor_json")" + + if [[ "$monitor_json" == "null" || -z "$monitor_json" ]]; then + log "No monitor found for cursor x=$cx y=$cy" + sleep "$POLL_INTERVAL" + continue + fi + + mon_name="$(jq -r '.name // .id // "unknown"' <<<"$monitor_json")" + mon_x="$(jq -r '.x' <<<"$monitor_json")" + mon_y="$(jq -r '.y' <<<"$monitor_json")" + mon_w="$(jq -r '.width' <<<"$monitor_json")" + mon_h="$(jq -r '.height' <<<"$monitor_json")" + mon_scale="$(jq -r '.scale' <<<"$monitor_json")" + + layout_w="$(awk "BEGIN {print $mon_w / $mon_scale}")" + layout_h="$(awk "BEGIN {print $mon_h / $mon_scale}")" + + layout_bottom="$(awk "BEGIN {print $mon_y + $layout_h}")" + + show_threshold="$(awk "BEGIN {print $layout_bottom - $SHOW_EDGE_SIZE}")" + keep_visible_threshold="$(awk "BEGIN {print $layout_bottom - $DOCK_HEIGHT}")" + + log "cursor=($cx,$cy) monitor=$mon_name raw=${mon_w}x${mon_h} scale=$mon_scale layout=${layout_w}x${layout_h} bottom=$layout_bottom show_threshold=$show_threshold keep_visible_threshold=$keep_visible_threshold" + + # 1) Cursor ganz unten -> Dock zeigen + if awk "BEGIN {exit !($cy >= $show_threshold)}"; then + log "ENTER SHOW EDGE on $mon_name" + show_dock + last_inside_dock_time="$now" + + # 2) Cursor ist auf dem Dock-Bereich -> sichtbar lassen + elif awk "BEGIN {exit !($cy >= $keep_visible_threshold)}"; then + log "INSIDE DOCK AREA on $mon_name" + last_inside_dock_time="$now" + + if ! dock_visible; then + log "SHOW DOCK because cursor is inside dock area" + show_dock + fi + + # 3) Cursor ist oberhalb des Dock-Bereichs -> ggf. verstecken + else + if dock_visible; then + delta="$(awk "BEGIN {print $now - $last_inside_dock_time}")" + log "ABOVE DOCK AREA delta=$delta" + + if awk "BEGIN {exit !($delta >= $HIDE_DELAY)}"; then + log "HIDE DOCK" + hide_dock + fi + fi + fi + + sleep "$POLL_INTERVAL" +done diff --git a/waybar/scripts/dock-toggle.sh b/waybar/scripts/dock-toggle.sh new file mode 100755 index 0000000..e9a951d --- /dev/null +++ b/waybar/scripts/dock-toggle.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +set -euo pipefail + +CONFIG="$HOME/.config/waybar/config-dock.jsonc" +STYLE="$HOME/.config/waybar/style-dock.css" +PIDFILE="/tmp/waybar-dock.pid" + +is_running() { + if [[ -f "$PIDFILE" ]]; then + local pid + pid="$(cat "$PIDFILE" 2>/dev/null || true)" + if [[ -n "${pid:-}" ]] && kill -0 "$pid" 2>/dev/null; then + return 0 + fi + fi + return 1 +} + +cleanup_pidfile() { + if [[ -f "$PIDFILE" ]]; then + local pid + pid="$(cat "$PIDFILE" 2>/dev/null || true)" + if [[ -z "${pid:-}" ]] || ! kill -0 "$pid" 2>/dev/null; then + rm -f "$PIDFILE" + fi + fi +} + +show() { + cleanup_pidfile + + if is_running; then + exit 0 + fi + + waybar -c "$CONFIG" -s "$STYLE" >/dev/null 2>&1 & + local pid=$! + + echo "$pid" >"$PIDFILE" + + # kurz prüfen, ob der Prozess wirklich lebt + sleep 0.1 + if ! kill -0 "$pid" 2>/dev/null; then + rm -f "$PIDFILE" + exit 1 + fi +} + +hide() { + cleanup_pidfile + + if ! is_running; then + exit 0 + fi + + local pid + pid="$(cat "$PIDFILE")" + + kill "$pid" 2>/dev/null || true + + # kurz warten, dann ggf. härter beenden + for _ in {1..10}; do + if ! kill -0 "$pid" 2>/dev/null; then + rm -f "$PIDFILE" + exit 0 + fi + sleep 0.05 + done + + kill -9 "$pid" 2>/dev/null || true + rm -f "$PIDFILE" +} + +toggle() { + cleanup_pidfile + + if is_running; then + hide + else + show + fi +} + +status() { + cleanup_pidfile + if is_running; then + echo "visible" + else + echo "hidden" + fi +} + +case "${1:-toggle}" in +show) + show + ;; +hide) + hide + ;; +toggle) + toggle + ;; +status) + status + ;; +*) + echo "Usage: $0 {show|hide|toggle|status}" + exit 1 + ;; +esac diff --git a/waybar/style-dock.css b/waybar/style-dock.css new file mode 100644 index 0000000..5e5a242 --- /dev/null +++ b/waybar/style-dock.css @@ -0,0 +1,8 @@ +window#waybar { + margin-bottom: -80px; + transition: margin 0.3s ease; +} + +window#waybar.visible { + margin-bottom: 10px; +}