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 {