diff --git a/fish/config.fish b/fish/config.fish index ff870d1..1ba739b 100644 --- a/fish/config.fish +++ b/fish/config.fish @@ -21,10 +21,16 @@ if test -e ~/.cache/wal/colors.fish end zoxide init --cmd cd fish | source set -gx PATH ~/.local/bin $PATH -if not pgrep --full ssh-agent | string collect > /dev/null - eval (ssh-agent -c) - set -Ux SSH_AGENT_PID $SSH_AGENT_PID - set -Ux SSH_AUTH_SOCK $SSH_AUTH_SOCK +# if not pgrep --full ssh-agent | string collect > /dev/null +# eval (ssh-agent -c) +# set -Ux SSH_AGENT_PID $SSH_AGENT_PID +# set -Ux SSH_AUTH_SOCK $SSH_AUTH_SOCK +# end +# Set SSH_AUTH_SOCK for GNOME Keyring / systemd +# The socket path is predictable +set -l GCR_SSH_SOCK $XDG_RUNTIME_DIR/gcr/ssh +if test -S "$GCR_SSH_SOCK" + set -gx SSH_AUTH_SOCK "$GCR_SSH_SOCK" end if uwsm check may-start && uwsm select exec uwsm start default diff --git a/hypr/modules/autostart.conf b/hypr/modules/autostart.conf index 9c652ff..babfdde 100644 --- a/hypr/modules/autostart.conf +++ b/hypr/modules/autostart.conf @@ -6,4 +6,4 @@ exec-once = uwsm app -- nm-applet exec-once = uwsm app -- nextcloud --background exec-once = uwsm app -- rclone mount google_drive: ~/gdrive exec-once = uwsm app -- protonvpn-app -exec-once = uwsm app -- sh -c "/usr/bin/discord discord --enable-features=UseOzonePlatform --ozone-platform=wayland --start-minimized &> /dev/null" +# exec-once = uwsm app -- sh -c "/usr/bin/discord --enable-features=UseOzonePlatform --ozone-platform=wayland --start-minimized &> /dev/null" diff --git a/hypr/scripts/droidcam-ctrl.sh b/hypr/scripts/droidcam-ctrl.sh new file mode 100755 index 0000000..fb6ddb4 --- /dev/null +++ b/hypr/scripts/droidcam-ctrl.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +PROGRAM_NAME="droidcam-cli" +PID_FILE="/tmp/droidcam.pid" +ANDROID_SERIAL=988e5035584a354b4430 + +start() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is already active." + exit 0 + fi + fi + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is starting ..." + + ANDROID_SERIAL=$ANDROID_SERIAL droidcam-cli -a -v -size=1920x1080 adb 4747 &> /dev/null & + echo $! > "$PID_FILE" +} + + +stop() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + kill "$PID" + rm "$PID_FILE" + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME has been stopped." + else + rm "$PID_FILE" # Stale PID file + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is not running." + fi + else + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is not running." + fi +} + +toggle() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + stop + else + rm "$PID_FILE" # Stale PID file + start + fi + else + start + fi +} + + +case "$1" in + start) + start + ;; + stop) + stop + ;; + toggle) + toggle + ;; + *) + echo "Usage: $0 {start|stop|save}" + exit 1 +esac + +exit 0 diff --git a/hypr/scripts/replay-ctrl.sh b/hypr/scripts/replay-ctrl.sh new file mode 100755 index 0000000..781869a --- /dev/null +++ b/hypr/scripts/replay-ctrl.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +PROGRAM_NAME="gpu-screen-recorder" +PID_FILE="/tmp/gpu-screen-recorder.pid" + +start() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is already active." + exit 0 + fi + fi + + video_path="$HOME/Videos/replay/" + mkdir -p "$video_path" + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is starting ..." + gpu-screen-recorder \ + -w screen \ + -f 60 \ + -a default_output -a default_input \ + -fm vfr \ + -c mkv \ + -encoder gpu \ + -bm qp \ + -cr full \ + -tune quality \ + -k av1_10bit \ + -q high \ + -r 120 \ + -replay-storage ram \ + -ab 320 \ + -cursor yes \ + -sc "$HOME/.config/hypr/scripts/replay-notification.sh" \ + -o "$video_path" &> /dev/null & + echo $! > "$PID_FILE" +} + +stop() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + kill "$PID" + rm "$PID_FILE" + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME has been stopped." + else + rm "$PID_FILE" # Stale PID file + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is not running." + fi + else + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is not running." + fi +} + +toggle() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + stop + else + rm "$PID_FILE" # Stale PID file + start + fi + else + start + fi +} + +save() { + if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + pkill -SIGUSR1 -f gpu-screen-recorder + else + # The process is not running, but the PID file exists. + # This can happen if the process crashed. + # We'll remove the stale PID file. + rm "$PID_FILE" + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is not running." + fi + else + notify-send -u low "$PROGRAM_NAME" "$PROGRAM_NAME is not running." + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + save) + save + ;; + toggle) + toggle + ;; + *) + echo "Usage: $0 {start|stop|save}" + exit 1 +esac + +exit 0 diff --git a/hypr/scripts/replay-notification.sh b/hypr/scripts/replay-notification.sh new file mode 100755 index 0000000..409d972 --- /dev/null +++ b/hypr/scripts/replay-notification.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +PROGRAM_NAME="gpu-screen-recorder" + +case "$2" in + replay) + notify-send -u low "$PROGRAM_NAME" "Replay saved: $1" + ;; + regular) + notify-send -u low "$PROGRAM_NAME" "Stream/Video saved: $1" + ;; + *) + echo "Usage: $0 {saved_file} {replay|regular}" + exit 1 +esac + +exit 0 diff --git a/hypr/scripts/restart_xdg-desktop-portal-hyprland.sh b/hypr/scripts/restart_xdg-desktop-portal-hyprland.sh new file mode 100755 index 0000000..15772d9 --- /dev/null +++ b/hypr/scripts/restart_xdg-desktop-portal-hyprland.sh @@ -0,0 +1,7 @@ +#!/bin/sh +sleep 1 +killall -e xdg-desktop-portal-hyprland +killall xdg-desktop-portal +/usr/lib/xdg-desktop-portal-hyprland & +sleep 2 +/usr/lib/xdg-desktop-portal & diff --git a/hypr/scripts/start_droidcam.sh b/hypr/scripts/start_droidcam.sh new file mode 100755 index 0000000..d31d9ec --- /dev/null +++ b/hypr/scripts/start_droidcam.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +scrcpy -d +ANDROID_SERIAL=988e5035584a354b4430 droidcam-cli -a -v -size=1920x1080 adb 4747 diff --git a/waybar/config.jsonc b/waybar/config.jsonc index b3b0149..eb67308 100644 --- a/waybar/config.jsonc +++ b/waybar/config.jsonc @@ -7,15 +7,14 @@ "modules-left": ["hyprland/workspaces"], "modules-center": [], "modules-right": [ - "tray", "wireplumber", "custom/audio-output", "network", "cpu", - "memory", + "memory", "custom/tlp", - "clock", - "custom/power" + "tray", + "clock" ], @@ -30,14 +29,20 @@ "clock": { "format": "{:%H:%M}", "format-alt": "{:%a, %b %d}", - "tooltip-format": "{:%Y %B}\n{calendar}" + "on-click-right": "xdg-open https://calendar.proton.me/u/0/month &> /dev/null & disown" + }, + "custom/gpu": { + "format": "GPU: {}%", + "exec": "~/.config/waybar/scripts/gpu_usage.sh", + "interval": 1, + "tooltip": true }, "cpu": { "format": "CPU: {usage}%", "tooltip": true }, "memory": { - "format": "MEM: {}%" + "format": "MEM: {used}/{total}GB" }, "network": { "format-wifi": "{essid} ({signalStrength}%): {ipaddr}", @@ -92,7 +97,8 @@ "critical": 15 }, "format": "{capacity}%", - "format-charging": "{capacity}%", "format-plugged": "{capacity}%", + "format-charging": "{capacity}%", + "format-plugged": "{capacity}%", "format-alt": "{time} {icon}", "format-full": "{capacity}%", "format-icons": ["", "", "", "", ""] @@ -101,14 +107,14 @@ "format": "{}", "return-type": "json", "exec": "~/.config/waybar/scripts/pixelbuds.sh", - "interval": 5, + "interval": 10, "on-click": "bluetoothctl disconnect B4:23:A2:09:D3:53" }, "custom/anc": { "format": "{}", "return-type": "json", "exec": "~/.config/waybar/scripts/anc_control.sh", - "interval": 5, + "interval": 10, "on-click": "~/.config/waybar/scripts/anc_control.sh off", "on-click-right": "~/.config/waybar/scripts/anc_control.sh cycle" }, @@ -120,9 +126,26 @@ "interval": 1 }, "custom/gamemode": { - "format": "󰮂", - "on-click": "~/.config/hypr/scripts/gamemode.sh" - } + "format": "{}", + "return-type": "json", + "exec": "~/.config/waybar/scripts/gamemode_status.sh", + "on-click": "~/.config/hypr/scripts/gamemode.sh", + "interval": 1 + }, + "custom/gpu-screen-recorder": { + "format": "{}", + "return-type": "json", + "exec": "~/.config/waybar/scripts/gpu-screen-recorder-status.sh", + "on-click-right": "~/.config/hypr/scripts/replay-ctrl.sh save", + "on-click": "~/.config/waybar/scripts/toggle-replay.sh", + "interval": 1 + }, + "custom/gpu-usage": { + "format": "{}", + "return-type": "json", + "exec": "~/.config/waybar/scripts/gpu_usage.sh", + "interval": 5 + } }, { "layer": "top", @@ -131,17 +154,16 @@ "modules-left": ["hyprland/workspaces"], "modules-center": [], "modules-right": [ - "tray", "wireplumber", "custom/audio-output", - "custom/pixelbuds", - "custom/anc", + "custom/pixelbuds", + "custom/anc", "network", "cpu", - "memory", + "memory", "custom/tlp", - "clock", - "custom/power" + "tray", + "clock" ], "hyprland/workspaces": { @@ -155,14 +177,20 @@ "clock": { "format": "{:%H:%M}", "format-alt": "{:%a, %b %d}", - "tooltip-format": "{:%Y %B}\n{calendar}" + "on-click-right": "xdg-open https://calendar.proton.me/u/0/month &> /dev/null & disown" + }, + "custom/gpu": { + "format": "GPU: {}%", + "exec": "~/.config/waybar/scripts/gpu_usage.sh", + "interval": 1, + "tooltip": true }, "cpu": { "format": "CPU: {usage}%", "tooltip": true }, "memory": { - "format": "MEM: {}%" + "format": "MEM: {used}/{total}GB" }, "network": { "format-wifi": "{essid} ({signalStrength}%): {ipaddr}", @@ -217,7 +245,8 @@ "critical": 15 }, "format": "{capacity}%", - "format-charging": "{capacity}%", "format-plugged": "{capacity}%", + "format-charging": "{capacity}%", + "format-plugged": "{capacity}%", "format-alt": "{time} {icon}", "format-full": "{capacity}%", "format-icons": ["", "", "", "", ""] @@ -226,14 +255,14 @@ "format": "{}", "return-type": "json", "exec": "~/.config/waybar/scripts/pixelbuds.sh", - "interval": 5, + "interval": 10, "on-click": "bluetoothctl disconnect B4:23:A2:09:D3:53" }, "custom/anc": { "format": "{}", "return-type": "json", "exec": "~/.config/waybar/scripts/anc_control.sh", - "interval": 5, + "interval": 10, "on-click": "~/.config/waybar/scripts/anc_control.sh off", "on-click-right": "~/.config/waybar/scripts/anc_control.sh cycle" }, @@ -245,9 +274,26 @@ "interval": 1 }, "custom/gamemode": { - "format": "󰮂", - "on-click": "~/.config/hypr/scripts/gamemode.sh" - } + "format": "{}", + "return-type": "json", + "exec": "~/.config/waybar/scripts/gamemode_status.sh", + "on-click": "~/.config/hypr/scripts/gamemode.sh", + "interval": 1 + }, + "custom/gpu-screen-recorder": { + "format": "{}", + "return-type": "json", + "exec": "~/.config/waybar/scripts/gpu-screen-recorder-status.sh", + "on-click-right": "~/.config/hypr/scripts/replay-ctrl.sh save", + "on-click": "~/.config/waybar/scripts/toggle-replay.sh", + "interval": 1 + }, + "custom/gpu-usage": { + "format": "{}", + "return-type": "json", + "exec": "~/.config/waybar/scripts/gpu_usage.sh", + "interval": 5 + } }] diff --git a/waybar/scripts/gamemode_status.sh b/waybar/scripts/gamemode_status.sh new file mode 100755 index 0000000..8079ef7 --- /dev/null +++ b/waybar/scripts/gamemode_status.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +HYPRGAMEMODE=$(hyprctl getoption animations:enabled | awk 'NR==1{print $2}') +if [ "$HYPRGAMEMODE" = 1 ] ; then + echo '{"text": "Gamemode", "tooltip": "Gamemode deactivated"}' +else + echo '{"text": "Gamemode", "tooltip": "Gamemode activated", "class": "active"}' +fi diff --git a/waybar/scripts/gpu-screen-recorder-status.sh b/waybar/scripts/gpu-screen-recorder-status.sh new file mode 100755 index 0000000..ad498d0 --- /dev/null +++ b/waybar/scripts/gpu-screen-recorder-status.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +PID_FILE="/tmp/gpu-screen-recorder.pid" + +if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if ps -p "$PID" > /dev/null; then + echo '{"text": "Replay", "tooltip": "Replay running", "class": "recording"}' + else + # The process is not running, but the PID file exists. + # This can happen if the process crashed. + # We'll remove the stale PID file. + rm "$PID_FILE" + echo '{"text": "Replay", "tooltip": "Replay paused"}' + fi +else + echo '{"text": "Replay", "tooltip": "Replay paused"}' +fi diff --git a/waybar/scripts/gpu_usage.sh b/waybar/scripts/gpu_usage.sh new file mode 100755 index 0000000..49a7d0c --- /dev/null +++ b/waybar/scripts/gpu_usage.sh @@ -0,0 +1,19 @@ +#!/bin/bash +USAGE=$(cat /sys/class/drm/card1/device/gpu_busy_percent) +MEM_USED=$(cat /sys/class/drm/card1/device/mem_info_vram_used) +MEM_TOTAL=$(cat /sys/class/drm/card1/device/mem_info_vram_total) +GPU=$(/opt/rocm/bin/rocm-smi --showproductname | grep "Card Series" | awk -F':' '{print $3}' | xargs) +TEXT="$USAGE% $(printf "%.2f\n" $(echo "scale=2; $MEM_USED/1024/1024/1024" | bc -l))/$(echo "scale=2; $MEM_TOTAL/1024/1024/1024" | bc -l)GB" +RATIO=$(echo "$MEM_USED/ $MEM_TOTAL" | bc -l) + +CLASS="" + +if (( $(echo "$USAGE > 95" | bc -l) )); then + CLASS="max_usage" +elif (( $(echo "$USAGE > 75" | bc -l) )); then + CLASS="high_usage" +else + CLASS="normal_usage" +fi + +echo "{\"text\":\"GPU: $TEXT\", \"tooltip\": \"$GPU\", \"class\":\"$CLASS\"}" diff --git a/waybar/scripts/toggle-replay.sh b/waybar/scripts/toggle-replay.sh new file mode 100755 index 0000000..412eeb3 --- /dev/null +++ b/waybar/scripts/toggle-replay.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +PID_FILE="/tmp/gpu-screen-recorder.pid" + +if [ -f "$PID_FILE" ] && ps -p "$(cat "$PID_FILE")" > /dev/null; then + $HOME/.config/hypr/scripts/replay-ctrl.sh stop +else + $HOME/.config/hypr/scripts/replay-ctrl.sh start +fi diff --git a/waybar/style.css b/waybar/style.css index 432fd48..0e8151c 100644 --- a/waybar/style.css +++ b/waybar/style.css @@ -55,6 +55,7 @@ window#waybar.hidden { #memory, #cpu, +#custom-gpu-usage, #custom-power, #custom-gamemode, #custom-tlp, @@ -66,10 +67,11 @@ window#waybar.hidden { #tray, #custom-pixelbuds, #custom-anc, -#custom-audio-output { +#custom-audio-output, +#custom-gpu-screen-recorder { border-radius: 4px; margin: 6px 3px; - padding: 6px 12px; + padding: 6px 16px 6px 12px; background-color: @base; color: @text; } @@ -92,10 +94,20 @@ window#waybar.hidden { #custom-anc.disconnected { } -#custom-power, +#custom-gpu-screen-recorder, #custom-gamemode { + color: @teal; + border-bottom: 3px solid @teal; +} + +#custom-power { color: @red; - padding: 6px 12px 6px 10px; +} + +#custom-gpu-screen-recorder.recording, +#custom-gamemode.active { + color: @red; + border-bottom: 3px solid @red; } #custom-tlp { @@ -136,10 +148,21 @@ window#waybar.hidden { } } +#custom-gpu-usage.max_usage { + color: @maroon; +} + +#custom-gpu-usage.high_usage { + color: @yellow; +} + +#custom-gpu-usage.normal_usage { + color: @teal; +} + #memory, #cpu { - color: @maroon; - border-bottom: 3px solid @maroon; + color: @teal; } @@ -165,7 +188,8 @@ window#waybar.hidden { #clock { font-family: JetBrainsMono Nerd Font; - color: @mauve; + color: @green; + border-bottom: 3px solid @green; } tooltip {