diff --git a/README.md b/README.md
index ab78066..8b365c0 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,10 @@ https://github.com/user-attachments/assets/7e2db305-58bc-4b3d-9c65-7dc0461aead7
-- Grub menu:
+
+
+
+Grub menu
@@ -41,7 +44,7 @@ https://github.com/user-attachments/assets/7e2db305-58bc-4b3d-9c65-7dc0461aead7
- Terminal: **Kitty** & Ghostty
- Power Menu: Wlogout
- Colorscheme: Catppuccin Mocha
-- App Launcher: Rofi
+- App Launcher: **Rofi** | fuzzel
- Desktop Widgets: Eww | **Quickshell**
- Wallpaper Daemon: Swww
- Notification Daemon: Mako | **Quickshell**
@@ -103,3 +106,37 @@ including:
- Sour Gummy
- Noto Sans
- ...
+
+## Some of the Scripts
+
+> [!TIP]
+>
+> Most scripts are placed in the `scripts` folder.
+
+- `config-sync`
+
+ creates symlinks in `~/.config/` referring to files and directories in `config` folder. If there is already a file or directorie or whatever with the same name in `~/config/`, it will be moved to `~/.config/config-backup/$(date +%Y%m%d-%H%M%S)/` before a new symlink is created.
+
+- `config-switch`
+
+ updats configurations of several apps according to the current (or given as parameter) desktop environment. e.g. Niri currently doesn't support blurred windows, so terminal emulators such as Kitty and Ghostty could reduce transparency for better appearences.
+
+- `change-colortheme`
+
+ changes the colortheme of a number of pre-configured apps. This is done by calling certain scripts that are usually called `apply-color`.
+
+- `wallpaper-daemon` & `change-wallpaper`
+
+ provides wallpaper for both Hyprland and Niri (background and backdrop). It can also automatically set the wallpaper to a blurred version when there is a window in focus, however, this is currently only implemented in Niri.
+
+- `ssh-init`
+
+ ensures that there is only one valid ssh-agent running at the same time. Useful when creating ssh-agent somewhere else than the login shell scripts or across sessions.
+
+- `screenshot`
+
+ takes a screenshot, and sends a notification asking whether to edit it by clicking on it. Works on both Hyprland and Niri.
+
+- `record-script`
+
+ records the screen based on wf-recorder and using av1_nvenc as the video encoder. The default codec parameters will generate a fairly large video file (80 Mbps), a later transcoding is definitly required in this case.
diff --git a/config/fish/post.d/sshs.fish b/config/fish/post.d/sshs.fish
index b47947c..f02fa45 100644
--- a/config/fish/post.d/sshs.fish
+++ b/config/fish/post.d/sshs.fish
@@ -1,9 +1,9 @@
# ssh with encrypted private keys
-# $ssh_keys should be set in advance or left empty to use default keys
+# $ssh_keys should be set in advance or left empty to use the default keys
if type -q ssh
bass $(ssh-init) > /dev/null 2>&1
- # only need to input passphrase once per session
+ # avoiding entering passphrase every time
function sshs
# test if keys are added to ssh-agent
if not ssh-add -l > /dev/null 2>&1
diff --git a/config/niri/config.kdl b/config/niri/config.kdl
index 85ca299..3d43d20 100644
--- a/config/niri/config.kdl
+++ b/config/niri/config.kdl
@@ -226,8 +226,8 @@ window-rule {
window-rule {
match app-id="blueberry"
match app-id="blueman-manager"
- match app-id="pavucontrol"
match app-id="org.pulseaudio.pavucontrol"
+ match app-id="com.saivert.pwvucontrol"
match app-id="Waydroid"
match app-id="org.kde.kcalc"
match app-id="org.kde.kalk"
@@ -300,6 +300,7 @@ binds {
Mod+Shift+T { spawn "ghostty"; }
Mod+Shift+Return { spawn "ghostty"; }
Mod+Shift+W { spawn "wallpaper-chooser"; }
+ Mod+P { spawn-sh "pkill -x -n pwvucontrol || pwvucontrol"; }
// Quickshell
Mod+Space { spawn-sh "qs ipc call panels toggleControlCenter"; }
diff --git a/config/quickshell/Modules/Bar/Components/Volume.qml b/config/quickshell/Modules/Bar/Components/Volume.qml
index b46ec1f..fa3400c 100644
--- a/config/quickshell/Modules/Bar/Components/Volume.qml
+++ b/config/quickshell/Modules/Bar/Components/Volume.qml
@@ -21,6 +21,6 @@ MonitorItem {
AudioService.toggleMute();
}
onRightClicked: {
- Quickshell.execDetached(["sh", "-c", "pkill -x -n pavucontrol || pavucontrol"]);
+ Quickshell.execDetached(["sh", "-c", "pkill -x -n pwvucontrol || pwvucontrol"]);
}
}
diff --git a/config/waybar/config.jsonc b/config/waybar/config.jsonc
index d8e3c74..c847bf1 100644
--- a/config/waybar/config.jsonc
+++ b/config/waybar/config.jsonc
@@ -1,247 +1,291 @@
{
- // -------------------------------------------------------------------------
- // Global configuration
- // -------------------------------------------------------------------------
- "layer": "bottom",
- "position": "top",
- "margin-left": 0,
- "margin-bottom": 0,
- "margin-right": 0,
- "spacing": 2, // Gaps between modules (px)
- "modules-left": [
- "custom/rofi",
- "custom/separator",
- "group/workspaceactions",
- "custom/separator",
- "hyprland/window",
- "custom/mediaplayer"
- ],
- "modules-center": ["clock"],
- "modules-right": ["group/monitors", "custom/separator", "group/tray-expander", "idle_inhibitor", "custom/power"],
- // -------------------------------------------------------------------------
- // Modules
- // -------------------------------------------------------------------------
- // Separators
- "custom/separator": {
- "format": "|"
- },
- // Buttons
- "custom/power": {
- "format": "",
- "tooltip": false,
- "on-click": "wlogout",
- "min-length": 2,
- "max-length": 2
- },
- "custom/rofi": {
- "format": "",
- "tooltip": false,
- // "on-click-right": "fuzzel -l 0 -p '>> ' | xargs -r sh -c",
- // "on-click": "fuzzel",
- // "on-click-middle": "pkill -9 fuzzel",
- "on-click": "eww open main --toggle",
- "on-click-right": "pkill rofi || rofi -show drun",
- "min-length": 2,
- "max-length": 2
- },
- "idle_inhibitor": {
- "format": "{icon}",
- "format-icons": {
- "activated": "",
- "deactivated": ""
+ // -------------------------------------------------------------------------
+ // Global configuration
+ // -------------------------------------------------------------------------
+ "layer": "bottom",
+ "position": "top",
+ "margin-left": 0,
+ "margin-bottom": 0,
+ "margin-right": 0,
+ "spacing": 2, // Gaps between modules (px)
+ "modules-left": [
+ "custom/rofi",
+ "custom/separator",
+ "group/workspaceactions",
+ "custom/separator",
+ "hyprland/window",
+ "custom/mediaplayer"
+ ],
+ "modules-center": [
+ "clock"
+ ],
+ "modules-right": [
+ "group/monitors",
+ "custom/separator",
+ "group/tray-expander",
+ "idle_inhibitor",
+ "custom/power"
+ ],
+ // -------------------------------------------------------------------------
+ // Modules
+ // -------------------------------------------------------------------------
+ // Separators
+ "custom/separator": {
+ "format": "|"
},
- "min-length": 2,
- "max-length": 2
- },
- // Time and Date
- "clock": {
- "format": "{:%H:%M | %e %b}",
- "tooltip-format": "{:%Y %B}\n{calendar}",
- "today-format": "{}"
- },
- // System monitors
- "group/monitors": {
- "modules": ["network#speed", "custom/publicip", "temperature", "memory", "cpu", "battery", "backlight", "wireplumber"],
- "orientation": "inherit"
- },
- "network#speed": {
- "interval": 1,
- "format": "{ifname}",
- "format-wifi": " {bandwidthDownBytes} {bandwidthUpBytes} ",
- "format-ethernet": " {bandwidthDownBytes} {bandwidthUpBytes} ",
- "format-disconnected": "",
- "tooltip-format": "{ipaddr}",
- "format-linked": " {ifname} (No IP)",
- "tooltip-format-wifi": "{essid} {signalStrength}%",
- "tooltip-format-ethernet": "{ifname} ",
- "tooltip-format-disconnected": " Disconnected",
- "min-length": 20
- },
- "custom/publicip": {
- "interval": 30,
- "return-type": "json",
- "format": " {text}",
- "tooltip-format": "{alt}",
- "max-length": 6,
- "min-length": 6,
- "exec": "$HOME/.config/waybar/modules/publicip.sh",
- "on-click": "rm -f $HOME/.config/waybar/modules/publicip.cache && sleep 0.1"
- },
- "temperature": {
- "interval": 5,
- "thermal-zone": 6,
- "hwmon-path": "/sys/class/hwmon/hwmon6/temp1_input",
- "critical-threshold": 80,
- // "format-critical": " {temperatureC}°C",
- "format-critical": " {temperatureC}°C",
- "format": "{icon} {temperatureC}°C",
- "format-icons": ["", "", ""],
- "max-length": 6,
- "min-length": 6
- },
- "memory": {
- "interval": 11,
- // "format": " {used:0.2f} / {total:0.0f} GB",
- "format": " {percentage}%",
- "on-click": "killall btop || ghostty -e btop",
- "max-length": 6,
- "min-length": 6
- },
- "cpu": {
- "interval": 3,
- //"format": " {}%", // Icon: microchip
- "format": " {usage}%",
- "max-length": 6,
- "min-length": 6,
- "on-click": "killall btop || ghostty -e btop"
- },
- "battery": {
- "interval": 30,
- "states": {
- "good": 95,
- "warning": 30,
- "critical": 15
+ // Buttons
+ "custom/power": {
+ "format": "",
+ "tooltip": false,
+ "on-click": "wlogout",
+ "min-length": 2,
+ "max-length": 2
},
- "format": "{icon} {capacity}%",
- "format-charging": " {capacity}%",
- "format-plugged": " {capacity}%",
- "format-icons": ["", "", "", "", ""],
- "max-length": 6,
- "min-length": 6
- },
- "backlight": {
- "device": "$DISPLAY_DEVICE",
- "format": "{icon} {percent}%",
- "format-alt": "{percent}% {icon}",
- "format-alt-click": "click-right",
- //"format-icons": ["", ""],
- "format-icons": [""],
- "on-scroll-down": "brightnessctl -d $BRIGHTNESSCTL_DEVICE set -5%",
- "on-scroll-up": "brightnessctl -d $BRIGHTNESSCTL_DEVICE set +5%",
- "max-length": 6,
- "min-length": 6
- },
- "wireplumber": {
- "on-click": "pavucontrol",
- //on-click: "${wpctl} set-mute @DEFAULT_AUDIO_SINK@ toggle";
- "on-scroll-down": "wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 0.04-",
- "on-scroll-up": "wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 0.04+",
- "format": "{icon} {volume}%",
- "format-muted": "",
- "format-source": "",
- "format-source-muted": "",
- //"format-muted": " ",
- //"format-icons": [ "" ]
- "format-icons": {
- "headphone": "",
- "phone": "",
- "portable": "",
- "car": "",
- "default": ["", "", "", "", "", ""]
+ "custom/rofi": {
+ "format": "",
+ "tooltip": false,
+ // "on-click-right": "fuzzel -l 0 -p '>> ' | xargs -r sh -c",
+ // "on-click": "fuzzel",
+ // "on-click-middle": "pkill -9 fuzzel",
+ "on-click": "eww open main --toggle",
+ "on-click-right": "pkill rofi || rofi -show drun",
+ "min-length": 2,
+ "max-length": 2
},
- "max-length": 6,
- "min-length": 6
- },
- // Hyprland
- "group/workspaceactions": {
- "modules": ["hyprland/workspaces#special", "hyprland/workspaces", "custom/workspacenew"],
- "orientation": "inherit"
- },
- "hyprland/workspaces": {
- "all-outputs": true,
- "format": "{id}",
- "on-scroll-up": "hyprctl dispatch workspace e+1 1>/dev/null",
- "on-scroll-down": "hyprctl dispatch workspace e-1 1>/dev/null",
- "sort-by-number": true,
- "active-only": false //,
+ "idle_inhibitor": {
+ "format": "{icon}",
+ "format-icons": {
+ "activated": "",
+ "deactivated": ""
+ },
+ "min-length": 2,
+ "max-length": 2
+ },
+ // Time and Date
+ "clock": {
+ "format": "{:%H:%M | %e %b}",
+ "tooltip-format": "{:%Y %B}\n{calendar}",
+ "today-format": "{}"
+ },
+ // System monitors
+ "group/monitors": {
+ "modules": [
+ "network#speed",
+ "custom/publicip",
+ "temperature",
+ "memory",
+ "cpu",
+ "battery",
+ "backlight",
+ "wireplumber"
+ ],
+ "orientation": "inherit"
+ },
+ "network#speed": {
+ "interval": 1,
+ "format": "{ifname}",
+ "format-wifi": " {bandwidthDownBytes} {bandwidthUpBytes} ",
+ "format-ethernet": " {bandwidthDownBytes} {bandwidthUpBytes} ",
+ "format-disconnected": "",
+ "tooltip-format": "{ipaddr}",
+ "format-linked": " {ifname} (No IP)",
+ "tooltip-format-wifi": "{essid} {signalStrength}%",
+ "tooltip-format-ethernet": "{ifname} ",
+ "tooltip-format-disconnected": " Disconnected",
+ "min-length": 20
+ },
+ "custom/publicip": {
+ "interval": 30,
+ "return-type": "json",
+ "format": " {text}",
+ "tooltip-format": "{alt}",
+ "max-length": 6,
+ "min-length": 6,
+ "exec": "$HOME/.config/waybar/modules/publicip.sh",
+ "on-click": "rm -f $HOME/.config/waybar/modules/publicip.cache && sleep 0.1"
+ },
+ "temperature": {
+ "interval": 5,
+ "thermal-zone": 6,
+ "hwmon-path": "/sys/class/hwmon/hwmon6/temp1_input",
+ "critical-threshold": 80,
+ // "format-critical": " {temperatureC}°C",
+ "format-critical": " {temperatureC}°C",
+ "format": "{icon} {temperatureC}°C",
+ "format-icons": [
+ "",
+ "",
+ ""
+ ],
+ "max-length": 6,
+ "min-length": 6
+ },
+ "memory": {
+ "interval": 11,
+ // "format": " {used:0.2f} / {total:0.0f} GB",
+ "format": " {percentage}%",
+ "on-click": "killall btop || ghostty -e btop",
+ "max-length": 6,
+ "min-length": 6
+ },
+ "cpu": {
+ "interval": 3,
+ //"format": " {}%", // Icon: microchip
+ "format": " {usage}%",
+ "max-length": 6,
+ "min-length": 6,
+ "on-click": "killall btop || ghostty -e btop"
+ },
+ "battery": {
+ "interval": 30,
+ "states": {
+ "good": 95,
+ "warning": 30,
+ "critical": 15
+ },
+ "format": "{icon} {capacity}%",
+ "format-charging": " {capacity}%",
+ "format-plugged": " {capacity}%",
+ "format-icons": [
+ "",
+ "",
+ "",
+ "",
+ ""
+ ],
+ "max-length": 6,
+ "min-length": 6
+ },
+ "backlight": {
+ "device": "$DISPLAY_DEVICE",
+ "format": "{icon} {percent}%",
+ "format-alt": "{percent}% {icon}",
+ "format-alt-click": "click-right",
+ //"format-icons": ["", ""],
+ "format-icons": [
+ ""
+ ],
+ "on-scroll-down": "brightnessctl -d $BRIGHTNESSCTL_DEVICE set -5%",
+ "on-scroll-up": "brightnessctl -d $BRIGHTNESSCTL_DEVICE set +5%",
+ "max-length": 6,
+ "min-length": 6
+ },
+ "wireplumber": {
+ "on-click": "pwvucontrol",
+ //on-click: "${wpctl} set-mute @DEFAULT_AUDIO_SINK@ toggle";
+ "on-scroll-down": "wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 0.04-",
+ "on-scroll-up": "wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 0.04+",
+ "format": "{icon} {volume}%",
+ "format-muted": "",
+ "format-source": "",
+ "format-source-muted": "",
+ //"format-muted": " ",
+ //"format-icons": [ "" ]
+ "format-icons": {
+ "headphone": "",
+ "phone": "",
+ "portable": "",
+ "car": "",
+ "default": [
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ "max-length": 6,
+ "min-length": 6
+ },
+ // Hyprland
+ "group/workspaceactions": {
+ "modules": [
+ "hyprland/workspaces#special",
+ "hyprland/workspaces",
+ "custom/workspacenew"
+ ],
+ "orientation": "inherit"
+ },
+ "hyprland/workspaces": {
+ "all-outputs": true,
+ "format": "{id}",
+ "on-scroll-up": "hyprctl dispatch workspace e+1 1>/dev/null",
+ "on-scroll-down": "hyprctl dispatch workspace e-1 1>/dev/null",
+ "sort-by-number": true,
+ "active-only": false //,
// "window-rewrite-default": "",
- // "window-rewrite": {
- // "class": "",
- // "class": "",
- // "class": "",
- // "class": "",
- // "class": "",
- // "class": ""
- // }
- },
- "hyprland/workspaces#special": {
- "persistent-workspaces": {
- "special:s": []
+ // "window-rewrite": {
+ // "class": "",
+ // "class": "",
+ // "class": "",
+ // "class": "",
+ // "class": "",
+ // "class": ""
+ // }
},
- "persistent-only": true,
- "show-special": true,
- "special-visible-only": false,
- "format": "S",
- "window-rewrite-default": "" //,
- // "window-rewrite": {
- // "class": "",
- // "class": "",
- // "class": "",
- // "class": "",
- // "class": "",
- // "class": ""
- // }
- },
- "custom/workspacenew": {
- "format": "+",
- "tooltip": false,
- "on-click": "workspace-new"
- },
- "hyprland/window": {
- "format": "",
- "max-length": 100,
- "separate-outputs": true,
- "icon": true,
- "on-click-middle": "hyprctl dispatch killactive",
- "icon-size": 14
- },
- "custom/mediaplayer": {
- "format": "{text}",
- "return-type": "json",
- "max-length": 100,
- "escape": true,
- "exec": "$HOME/.config/waybar/modules/mediaplayer.py 2> /dev/null",
- "on-click": "playerctl play-pause",
- "on-click-right": "lyrics-widgets",
- "on-scroll-up": "playerctl next",
- "on-scroll-down": "playerctl previous"
- },
- "group/tray-expander": {
- "orientation": "inherit",
- "drawer": {
- "transition-duration": 600,
- "children-class": "tray-group-item"
+ "hyprland/workspaces#special": {
+ "persistent-workspaces": {
+ "special:s": []
+ },
+ "persistent-only": true,
+ "show-special": true,
+ "special-visible-only": false,
+ "format": "S",
+ "window-rewrite-default": "" //,
+ // "window-rewrite": {
+ // "class": "",
+ // "class": "",
+ // "class": "",
+ // "class": "",
+ // "class": "",
+ // "class": ""
+ // }
},
- "modules": ["custom/expand-icon", "tray", "custom/separator"]
- },
- "custom/expand-icon": {
- "format": "",
- "tooltip": false,
- "min-length": 2,
- "max-length": 2
- },
- "tray": {
- "icon-size": 15,
- "spacing": 5
- }
+ "custom/workspacenew": {
+ "format": "+",
+ "tooltip": false,
+ "on-click": "workspace-new"
+ },
+ "hyprland/window": {
+ "format": "",
+ "max-length": 100,
+ "separate-outputs": true,
+ "icon": true,
+ "on-click-middle": "hyprctl dispatch killactive",
+ "icon-size": 14
+ },
+ "custom/mediaplayer": {
+ "format": "{text}",
+ "return-type": "json",
+ "max-length": 100,
+ "escape": true,
+ "exec": "$HOME/.config/waybar/modules/mediaplayer.py 2> /dev/null",
+ "on-click": "playerctl play-pause",
+ "on-click-right": "lyrics-widgets",
+ "on-scroll-up": "playerctl next",
+ "on-scroll-down": "playerctl previous"
+ },
+ "group/tray-expander": {
+ "orientation": "inherit",
+ "drawer": {
+ "transition-duration": 600,
+ "children-class": "tray-group-item"
+ },
+ "modules": [
+ "custom/expand-icon",
+ "tray",
+ "custom/separator"
+ ]
+ },
+ "custom/expand-icon": {
+ "format": "",
+ "tooltip": false,
+ "min-length": 2,
+ "max-length": 2
+ },
+ "tray": {
+ "icon-size": 15,
+ "spacing": 5
+ }
}
diff --git a/memo/hyprland-ricing.txt b/memo/hyprland-ricing.txt
index b99f292..25b8914 100644
--- a/memo/hyprland-ricing.txt
+++ b/memo/hyprland-ricing.txt
@@ -50,7 +50,7 @@ rofi(-wayland)
mpv
network-manager-applet # nm-applet
blueman # bluetooth GUI & applet
-pavucontrol
+pwvucontrol
gnome-text-editor # or kwrite, notepad replacement
btop # system monitor
activate-linux # :/
@@ -72,4 +72,4 @@ kvantum
bc
jq
python-colorthief
-python-watchdog
\ No newline at end of file
+python-watchdog
diff --git a/scripts/config-switch b/scripts/config-switch
index 21329aa..e9a10eb 100755
--- a/scripts/config-switch
+++ b/scripts/config-switch
@@ -13,14 +13,14 @@ for item in "kitty" "ghostty" "wlogout"; do
if [ -L "$HOME/.config/$target" ]; then
rm -v "$HOME/.config/$target"
elif [ -e "$HOME/.config/$target" ]; then
- echo "Error: $HOME/.config/$target is not a symlink." >&2
+ echo "Error: $HOME/.config/$target exists and is not a symlink." >&2
exit 1
fi
done
if [ "$desktop" = "niri" ]; then
- ln -sv "$path/../config/$item-niri" "$HOME/.config/$item"
+ ln -sv "$(realpath --relative-to="$HOME/.config" "$path/../config/$item-niri")" "$HOME/.config/$item"
else
- ln -sv "$path/../config/$item" "$HOME/.config/$item"
+ ln -sv "$(realpath --relative-to="$HOME/.config" "$path/../config/$item")" "$HOME/.config/$item"
fi
done
\ No newline at end of file
diff --git a/scripts/config-load b/scripts/config-sync
similarity index 100%
rename from scripts/config-load
rename to scripts/config-sync
diff --git a/utils/apply-color-helper b/utils/apply-color-helper
index ec7be02..8fc4244 100644
--- a/utils/apply-color-helper
+++ b/utils/apply-color-helper
@@ -1,3 +1,8 @@
+[ "$(basename "$0")" = "apply-color-helper" ] && {
+ echo "This script is meant to be sourced, not executed directly."
+ exit 1
+}
+
[ -z "$1" ] && exit 1
palette="$1"
[ -z "$2" ] && exit 1