diff --git a/.config/hypr/conf.d/40-keybinds.conf##hostname.cn-arch b/.config/hypr/conf.d/40-keybinds.conf##hostname.cn-arch
index a7a66e0..e48b942 100644
--- a/.config/hypr/conf.d/40-keybinds.conf##hostname.cn-arch
+++ b/.config/hypr/conf.d/40-keybinds.conf##hostname.cn-arch
@@ -78,13 +78,10 @@ bind = $mainMod, A, exec, $nothide
bind = $mainMod SHIFT, A, exec, $notclose
bind = $mainMod CTRL, A, exec, $notcloseall
-# Screenshot
-#bind = ALT SHIFT, 3, exec, GRIMBLAST_EDITOR="satty -f" grimblast --notify edit output
-#bind = ALT SHIFT, 4, exec, GRIMBLAST_EDITOR="satty -f" grimblast --notify edit area
-
-#testing stuff
-bind = ALT SHIFT, 3, exec, GRIMBLAST_EDITOR="/home/cnachtigall/data/git/clone/Satty/target/debug/satty -f" grimblast --notify edit output
-bind = ALT SHIFT, 4, exec, GRIMBLAST_EDITOR="/home/cnachtigall/data/git/clone/Satty/target/debug/satty -f" grimblast --notify edit area
+# Screenshot & picking
+bind = ALT SHIFT, 3, exec, ~/.config/hypr/scripts/hyprshot-wrapper.sh output active
+bind = ALT SHIFT, 4, exec, ~/.config/hypr/scripts/hyprshot-wrapper.sh region
+bind = ALT SHIFT, C, exec, hyprpicker --autocopy --format=hex
# Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l
@@ -140,6 +137,11 @@ bindl = , XF86AudioNext, exec, playerctl next
# SwayOSD
# Sink volume change
+
+# Hyprshade
+bind = $mainMod, F6, exec, bash -lc 'command -v hyprshade >/dev/null && hyprshade toggle dim'
+bind = $mainMod, F7, exec, bash -lc 'command -v hyprshade >/dev/null && hyprshade toggle reading'
+
bindel = , XF86AudioRaiseVolume, exec, swayosd-client --output-volume raise
bindel = , XF86AudioLowerVolume, exec, swayosd-client --output-volume lower
# Sink volume toggle mute
diff --git a/.config/hypr/conf.d/50-autostart.conf##hostname.cn-arch b/.config/hypr/conf.d/50-autostart.conf##hostname.cn-arch
index 4e9b23f..696a370 100644
--- a/.config/hypr/conf.d/50-autostart.conf##hostname.cn-arch
+++ b/.config/hypr/conf.d/50-autostart.conf##hostname.cn-arch
@@ -1,10 +1,10 @@
# ~/.config/hypr/conf.d/50-autostart.conf
exec-once = dbus-update-activation-environment --all
-exec-once = uwsm app -- polkit-gnome-authentication-agent-1
+exec-once = uwsm app -- /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
exec-once = uwsm app -- swaync
exec-once = uwsm app -- waybar
-exec-once = uwsm app -- xdg-desktop-portal-hyprland
+exec-once = uwsm app -- /usr/lib/xdg-desktop-portal-hyprland/xdg-desktop-portal-hyprland
exec-once = xsettingsd
exec-once = ~/.config/waybar/scripts/hyprsunset_daemon.sh
diff --git a/.config/hypr/hypridle.conf##hostname.cn-arch b/.config/hypr/hypridle.conf##hostname.cn-arch
index 475d102..1d804aa 100644
--- a/.config/hypr/hypridle.conf##hostname.cn-arch
+++ b/.config/hypr/hypridle.conf##hostname.cn-arch
@@ -6,6 +6,13 @@ general {
after_sleep_cmd = hyprctl dispatch dpms on
}
+# Pre-lock dimming
+listener {
+ timeout = 480
+ on-timeout = bash -lc 'command -v hyprshade >/dev/null && hyprshade on dim'
+ on-resume = bash -lc 'command -v hyprshade >/dev/null && hyprshade off dim'
+}
+
# Lock after 10 minutes
listener {
timeout = 600
diff --git a/.config/hypr/scripts/hyprshot-wrapper.sh b/.config/hypr/scripts/hyprshot-wrapper.sh
new file mode 100755
index 0000000..b6104c2
--- /dev/null
+++ b/.config/hypr/scripts/hyprshot-wrapper.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+if [[ $# -eq 0 ]]; then
+ echo "Usage: hyprshot-wrapper.sh MODE [MODE ...]" >&2
+ exit 1
+fi
+
+modes=()
+for mode in "$@"; do
+ modes+=("-m" "$mode")
+done
+
+screens_dir="${XDG_PICTURES_DIR:-$HOME/Pictures}/Screenshots"
+mkdir -p "$screens_dir"
+
+stamp=$(date +'%Y-%m-%d_%H-%M-%S')
+filename="Screenshot_${stamp}.png"
+filepath="$screens_dir/$filename"
+
+if ! hyprshot --freeze "${modes[@]}" --output-folder "$screens_dir" --filename "$filename"; then
+ exit $?
+fi
+
+if [[ -f "$filepath" ]]; then
+ if command -v wl-copy >/dev/null 2>&1; then
+ wl-copy < "$filepath" || true
+ fi
+
+ satty_bin="${SATTY_BIN:-$HOME/data/git/clone/Satty/target/debug/satty}"
+ if [[ -x "$satty_bin" ]]; then
+ if command -v uwsm >/dev/null 2>&1; then
+ uwsm app -- "$satty_bin" -f "$filepath" &
+ else
+ "$satty_bin" -f "$filepath" &
+ fi
+ fi
+fi
diff --git a/.config/jellyfin-mpv-shim/conf.json b/.config/jellyfin-mpv-shim/conf.json
deleted file mode 100644
index 57f426f..0000000
--- a/.config/jellyfin-mpv-shim/conf.json
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "allow_transcode_to_h265": true,
- "always_transcode": false,
- "audio_output": "hdmi",
- "auto_play": false,
- "check_updates": true,
- "client_uuid": "a39904c0-f818-41d4-ab53-d72cb01bee16",
- "connect_retry_mins": 0,
- "direct_paths": false,
- "discord_presence": false,
- "display_mirroring": false,
- "enable_gui": true,
- "enable_osc": true,
- "force_audio_codec": null,
- "force_set_played": false,
- "force_video_codec": "['av1', 'h265', 'h264']",
- "fullscreen": true,
- "health_check_interval": 300,
- "idle_cmd": null,
- "idle_cmd_delay": 60,
- "idle_ended_cmd": null,
- "idle_when_paused": false,
- "ignore_ssl_cert": false,
- "kb_debug": "~",
- "kb_fullscreen": "f",
- "kb_kill_shader": "k",
- "kb_menu": "c",
- "kb_menu_down": "down",
- "kb_menu_esc": "esc",
- "kb_menu_left": "left",
- "kb_menu_ok": "enter",
- "kb_menu_right": "right",
- "kb_menu_up": "up",
- "kb_next": ">",
- "kb_pause": "space",
- "kb_prev": "<",
- "kb_stop": "q",
- "kb_unwatched": "u",
- "kb_watched": "w",
- "lang": null,
- "lang_filter": "und,eng,jpn,mis,mul,zxx",
- "lang_filter_audio": false,
- "lang_filter_sub": false,
- "local_kbps": 2147483,
- "log_decisions": false,
- "media_ended_cmd": null,
- "media_key_seek": false,
- "media_keys": true,
- "menu_mouse": true,
- "mpv_ext": false,
- "mpv_ext_ipc": null,
- "mpv_ext_no_ovr": false,
- "mpv_ext_path": null,
- "mpv_ext_start": true,
- "mpv_log_level": "info",
- "notify_updates": true,
- "play_cmd": null,
- "playback_timeout": 30,
- "player_name": "cn-arch",
- "pre_media_cmd": null,
- "prefer_transcode_to_h265": true,
- "raise_mpv": true,
- "remote_direct_paths": false,
- "remote_kbps": 25000,
- "sanitize_output": true,
- "screenshot_dir": null,
- "screenshot_menu": true,
- "seek_down": -60,
- "seek_h_exact": false,
- "seek_left": -5,
- "seek_right": 5,
- "seek_up": 60,
- "seek_v_exact": false,
- "shader_pack_custom": false,
- "shader_pack_enable": true,
- "shader_pack_profile": null,
- "shader_pack_remember": true,
- "shader_pack_subtype": "lq",
- "skip_credits_always": false,
- "skip_credits_enable": true,
- "skip_intro_always": true,
- "skip_intro_enable": true,
- "stop_cmd": null,
- "stop_idle": false,
- "subtitle_color": "#FFFFFFFF",
- "subtitle_position": "bottom",
- "subtitle_size": 100,
- "svp_enable": false,
- "svp_socket": null,
- "svp_url": "http://127.0.0.1:9901/",
- "sync_attempts": 5,
- "sync_max_delay_skip": 300,
- "sync_max_delay_speed": 50,
- "sync_method_thresh": 2000,
- "sync_osd_message": true,
- "sync_revert_seek": true,
- "sync_speed_attempts": 3,
- "sync_speed_time": 1000,
- "thumbnail_enable": true,
- "thumbnail_osc_builtin": true,
- "thumbnail_preferred_size": 320,
- "tls_client_cert": null,
- "tls_client_key": null,
- "tls_server_ca": null,
- "transcode_4k": false,
- "transcode_av1": false,
- "transcode_dolby_vision": true,
- "transcode_hdr": true,
- "transcode_hevc": false,
- "transcode_hi10p": false,
- "transcode_warning": true,
- "use_web_seek": false,
- "write_logs": false
-}
\ No newline at end of file
diff --git a/.config/jellyfin-mpv-shim/cred.json b/.config/jellyfin-mpv-shim/cred.json
deleted file mode 100644
index a612971..0000000
--- a/.config/jellyfin-mpv-shim/cred.json
+++ /dev/null
@@ -1 +0,0 @@
-[{"address": "https://j.someho.me", "Name": "IdleJelly", "Id": "cef99817a4124734937e2fb674ce2065", "Version": "10.10.7", "DateLastAccessed": "2025-05-10T01:31:14Z", "UserId": "0eb92b7cdbeb489b9ea54be1757579b8", "AccessToken": "1ebec612c3a64a61889fc4926a057cfd", "Users": [{"Id": "0eb92b7cdbeb489b9ea54be1757579b8", "IsSignedInOffline": true}], "uuid": "72aeed57-a0eb-4cf3-bf1f-3601b70036ce", "username": "vikingowl", "connected": true}]
\ No newline at end of file
diff --git a/.config/waybar/.idea/.gitignore b/.config/waybar/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.config/waybar/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.config/waybar/.idea/dbnavigator.xml b/.config/waybar/.idea/dbnavigator.xml
new file mode 100644
index 0000000..95eff9e
--- /dev/null
+++ b/.config/waybar/.idea/dbnavigator.xml
@@ -0,0 +1,434 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.config/waybar/.idea/misc.xml b/.config/waybar/.idea/misc.xml
new file mode 100644
index 0000000..e4c3050
--- /dev/null
+++ b/.config/waybar/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.config/waybar/.idea/modules.xml b/.config/waybar/.idea/modules.xml
new file mode 100644
index 0000000..e62c08b
--- /dev/null
+++ b/.config/waybar/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.config/waybar/.idea/waybar.iml b/.config/waybar/.idea/waybar.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.config/waybar/.idea/waybar.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.config/waybar/base.jsonc##hostname.cn-arch b/.config/waybar/base.jsonc##hostname.cn-arch
index 660f230..e133f91 100644
--- a/.config/waybar/base.jsonc##hostname.cn-arch
+++ b/.config/waybar/base.jsonc##hostname.cn-arch
@@ -154,6 +154,14 @@
"tooltip": true,
"on-click": "alacritty -e watch -n 1 sensors",
},
+ "custom/hyprsysteminfo": {
+ "exec-if": "[ -x $HOME/.config/waybar/scripts/hyprsysteminfo.sh ]",
+ "exec": "$HOME/.config/waybar/scripts/hyprsysteminfo.sh",
+ "return-type": "json",
+ "interval": 5,
+ "tooltip": true,
+ "on-click": "bash -lc 'command -v hyprsysteminfo >/dev/null && uwsm app -- hyprsysteminfo'",
+ },
"custom/hyprsunset": {
"exec-if": "[ -x $HOME/.config/waybar/scripts/hyprsunset_toggle.sh ]",
"exec": "$HOME/.config/waybar/scripts/hyprsunset_toggle.sh --print",
diff --git a/.config/waybar/conf.d/dp1.jsonc##hostname.cn-arch b/.config/waybar/conf.d/dp1.jsonc##hostname.cn-arch
index a89b1b6..725ee57 100644
--- a/.config/waybar/conf.d/dp1.jsonc##hostname.cn-arch
+++ b/.config/waybar/conf.d/dp1.jsonc##hostname.cn-arch
@@ -11,6 +11,7 @@
"bluetooth",
"battery",
"power-profiles-daemon",
+ "custom/hyprsysteminfo",
"custom/hyprsunset",
"tray",
"clock",
diff --git a/.config/waybar/conf.d/dp2.jsonc##hostname.cn-arch b/.config/waybar/conf.d/dp2.jsonc##hostname.cn-arch
index 38f495a..9c5a530 100644
--- a/.config/waybar/conf.d/dp2.jsonc##hostname.cn-arch
+++ b/.config/waybar/conf.d/dp2.jsonc##hostname.cn-arch
@@ -17,6 +17,7 @@
"custom/alhp",
"custom/razer-mouse-battery",
"custom/temps",
+ "custom/hyprsysteminfo",
"custom/hyprsunset",
"tray",
"clock",
diff --git a/.config/waybar/conf.d/hdmi.jsonc##hostname.cn-arch b/.config/waybar/conf.d/hdmi.jsonc##hostname.cn-arch
index 8899625..250f4ac 100644
--- a/.config/waybar/conf.d/hdmi.jsonc##hostname.cn-arch
+++ b/.config/waybar/conf.d/hdmi.jsonc##hostname.cn-arch
@@ -10,6 +10,7 @@
"pulseaudio",
"bluetooth",
"battery",
+ "custom/hyprsysteminfo",
"custom/hyprsunset",
"tray",
"clock",
diff --git a/.config/waybar/scripts/hyprsysteminfo.sh b/.config/waybar/scripts/hyprsysteminfo.sh
new file mode 100755
index 0000000..5b9e1dd
--- /dev/null
+++ b/.config/waybar/scripts/hyprsysteminfo.sh
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+import json
+import os
+import shutil
+import subprocess
+import sys
+from datetime import datetime
+
+ICON = "Hypr"
+
+def run_json(cmd):
+ try:
+ out = subprocess.run(cmd, capture_output=True, text=True, check=True).stdout.strip()
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ return None
+ if not out:
+ return None
+ try:
+ return json.loads(out)
+ except json.JSONDecodeError:
+ return None
+
+def run_text(cmd):
+ try:
+ return subprocess.run(cmd, capture_output=True, text=True, check=True).stdout.strip()
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ return ""
+
+hypr_info = {}
+if shutil.which("hyprsysteminfo"):
+ proc = subprocess.run(["hyprsysteminfo", "--json"], capture_output=True, text=True)
+ if proc.returncode == 0 and proc.stdout.strip():
+ try:
+ hypr_info = json.loads(proc.stdout)
+ except json.JSONDecodeError:
+ hypr_info = {}
+
+active_window = run_json(["hyprctl", "-j", "activewindow"]) or {}
+monitors = run_json(["hyprctl", "-j", "monitors"]) or []
+clients = run_json(["hyprctl", "-j", "clients"]) or []
+
+focused_monitor = next((m for m in monitors if m.get("focused")), {})
+monitor_name = focused_monitor.get("name") or active_window.get("monitor") or "?"
+workspace = ""
+ws_data = active_window.get("workspace") or focused_monitor.get("activeWorkspace")
+if isinstance(ws_data, dict):
+ workspace = ws_data.get("name") or ""
+active_title = active_window.get("title") or active_window.get("class") or ""
+layout = focused_monitor.get("layout") or ""
+windows_on_monitor = sum(1 for c in clients if c.get("monitor") == monitor_name)
+
+hypr_version = ""
+if hypr_info:
+ for key in ("Hyprland", "hyprland"):
+ section = hypr_info.get(key)
+ if isinstance(section, dict):
+ hypr_version = section.get("version") or section.get("git") or ""
+ if hypr_version:
+ break
+
+uptime = run_text(["uptime", "-p"]).replace("up ", "")
+
+text_parts = ["", monitor_name]
+if workspace:
+ text_parts.append(f"[{workspace}]")
+text = " ".join(part for part in text_parts if part)
+
+tooltip_lines = []
+if hypr_version:
+ tooltip_lines.append(f"Hyprland: {hypr_version}")
+if layout:
+ tooltip_lines.append(f"Layout: {layout}")
+if workspace:
+ tooltip_lines.append(f"Workspace: {workspace}")
+if active_title:
+ tooltip_lines.append(f"Window: {active_title}")
+if uptime:
+ tooltip_lines.append(f"System uptime: {uptime}")
+if windows_on_monitor:
+ tooltip_lines.append(f"Windows on monitor: {windows_on_monitor}")
+if not tooltip_lines:
+ tooltip_lines.append("Hyprland ready")
+
+print(json.dumps({
+ "text": text,
+ "tooltip": "\n".join(tooltip_lines),
+ "class": ["hypr", f"workspace-{workspace}" if workspace else "hypr-no-ws"]
+}))
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6905768
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+style.css
+
+.config/jellyfin-mpv-shim/cred.json
+.config/jellyfin-mpv-shim/conf.json