diff --git a/.Xresources b/.Xresources index 4bff6266..172db4df 100644 --- a/.Xresources +++ b/.Xresources @@ -5,3 +5,7 @@ Xft.hintstyle: hintslight Xft.rgba: none Xft.lcdfilter: lcddefault Xcursor.theme: Remus-Black + +Nsxiv.window.background: #000000 +Nsxiv.bar.background: #1c1c1c +Nsxiv.bar.foreground: #d4d4d4 diff --git a/.config/awesome/wm_applications.lua b/.config/awesome/wm_applications.lua index 6d647579..65d43df0 100644 --- a/.config/awesome/wm_applications.lua +++ b/.config/awesome/wm_applications.lua @@ -25,7 +25,7 @@ local groupLuci4 = "luci4" local groupLauncher = "launcher" local browserCmd = "librewolf" -local terminalCmd = "kitty" +local terminalCmd = "kitty --single-instance" local editorCmd = terminalCmd .. " -e " .. (os.getenv("EDITOR") or "nvim") local modkey = "Mod4" @@ -194,7 +194,7 @@ local muteVolume = { } } local brightnessUp = { - command = homeDir .. "/scripts/shell_common/brightnessctl.sh --inc", + command = homeDir .. "/scripts/wm_common/brightnessctl.sh --inc", description = "Increase screen brightness", group = groupLuci4, shell = false, @@ -204,7 +204,7 @@ local brightnessUp = { } } local brightnessDown = { - command = homeDir .. "/scripts/shell_common/brightnessctl.sh --dec", + command = homeDir .. "/scripts/wm_common/brightnessctl.sh --dec", description = "Decrease screen brightness", group = groupLuci4, shell = false, @@ -301,11 +301,20 @@ local resetTor = { group = groupLuci4, shell = true, keyBinding = { - key1 = { modkey }, + key1 = { modkey, "Mod1" }, key2 = "i" } } - +local resetPicom = { + command = homeDir .. "/scripts/reset-picom.sh", + description = "Reset picom", + group = groupLuci4, + shell = true, + keyBinding = { + key1 = { modkey, "Mod1" }, + key2 = "p" + } +} local placement = { centered = "centered", bottom_right = "bottom_right", @@ -405,6 +414,9 @@ local applications = { askOllama = { command = askOllama }, + resetPicom = { + command = resetPicom + }, resetTor = { command = resetTor }, @@ -416,7 +428,24 @@ local applications = { icon = icons.kitty, favourite = true }, - editor = { + terminalQuake = { + label = "Kitty Quake Terminal", + class = "kitty-quick-access", + command = { + command = "kitten quick-access-terminal", + description = "Open a Quake-style terminal", + group = groupLauncher, + shell = false, + keyBinding = { + key1 = { modkey, "Shift" }, + key2 = "Return" + } + }, + subGroup = subGroup.terminals, + icon = icons.kitty, + favourite = true + }, + editor = { label = "NeoVim", class = "", command = editor, @@ -555,8 +584,12 @@ local applications = { command = { command = "keepassxc", description = "Password manager", - group = "", - shell = false + group = groupLuci4, + shell = false, + keyBinding = { + key1 = { modkey, "Shift" }, + key2 = "x" + } }, subGroup = subGroup.utils, -- icon = icons.keePass, @@ -714,13 +747,17 @@ local applications = { command = { command = "flatpak run im.nheko.Nheko", description = "Nheko messenger", - group = "", - shell = false + group = groupLuci4, + shell = false, + keyBinding = { + key1 = { modkey }, + key2 = "z" + } }, subGroup = subGroup.messaging, -- icon = icons.telegram, properties = { - tag = "8", + -- tag = "8", floating = true, width = 1100, height = 800, @@ -1212,8 +1249,8 @@ local applications = { class = "", favourite = false, command = { - command = homeDir .. "/apps/Audacity.AppImage", - description = "Audacity audio editor", + command = homeDir .. "/apps/Tenacity.AppImage", + description = "Tenacity audio editor", group = "", shell = false }, diff --git a/.config/distrobox/distrobox.ini b/.config/distrobox/distrobox.ini new file mode 100644 index 00000000..c6f50f80 --- /dev/null +++ b/.config/distrobox/distrobox.ini @@ -0,0 +1,9 @@ +[music-arch] +image="quay.io/toolbx/arch-toolbox:latest" +home="/mnt/lucie/distrobox-home/music" +additional_packages="picard pipewire pipewire-pulse pipewire-alsa libpulse git curl fish neovim lua luarocks" +pre_init_hooks="export SHELL=/usr/bin/fish;" +# mnt volumes are already mounted by default +pull=true +replace=false + diff --git a/.config/distrobox/link_configs.sh b/.config/distrobox/link_configs.sh new file mode 100644 index 00000000..672b3845 --- /dev/null +++ b/.config/distrobox/link_configs.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# +# link_configs.sh - Symlink dotfiles from source to destination home directory +# +# Usage: +# ./link_configs.sh /home/lucie/dotfiles /home/lucie +# +# Arguments: +# homeDirSource - Directory containing the original config files/dirs +# homeDirDest - Destination home directory where symlinks will be created +# +# Notes: +# - Edit the 'paths' array below to add/remove configurations +# - Handles both files and directories (e.g. .config/fish/config.fish) +# - Parent directories are created automatically in the destination +# - Existing symlinks are overwritten (-f flag) + +homeDirSource="$1" +homeDirDest="$2" + +paths=( + ".config/fontconfig" + ".local/share" + ".config/gtk-3.0" + ".config/gtk-4.0" + ".config/qt5ct" + ".config/qt6ct" + ".config/Kvantum" + ".config/fish/config.fish" + ".config/fish/conf.d" + ".config/fish/functions" + ".config/kitty" + ".config/nvim" + ".local/share/themes" + ".local/share/icons" + ".local/share/fonts" + "scripts" + ".shell_env" +) + +for p in "${paths[@]}"; do + mkdir -p "${homeDirDest}/$(dirname "${p}")" + ln -sf "${homeDirSource}/${p}" "${homeDirDest}/${p}" +done + diff --git a/.config/fish/config.fish b/.config/fish/config.fish index 350c7391..a0eb16fa 100644 --- a/.config/fish/config.fish +++ b/.config/fish/config.fish @@ -150,10 +150,13 @@ if status is-interactive ### OS SPECIFIC ### if test (uname -s) = "Darwin" - set OS_NAME (sw_vers -productName) + set -g OS_NAME macos else - set OS_NAME (lsb_release -is) - end + set -g OS_NAME linux + if test -e /etc/os-release + set -g OS_NAME (grep '^ID=' /etc/os-release | string replace -r '^ID="?(.+)"?$' '$1') + end + end # if the variable $CONTAINER_ID exists, the sessions is in a distrobox container if test -n "$CONTAINER_ID" @@ -163,11 +166,11 @@ if status is-interactive end switch $OS_NAME - case "Ubuntu" + case "ubuntu" abbr --add ca batcat --color=always alias cat='batcat -p --color=always' abbr --add upd "sudo apt update && sudo apt upgrade -y" - case "Arch" + case "arch" abbr --add ca bat --color=always alias cat='bat -p --color=always' # pacman and yay @@ -184,7 +187,7 @@ if status is-interactive alias mirrors="sudo reflector --latest 50 --number 20 --sort score --save /etc/pacman.d/mirrorlist" alias mirrora="sudo reflector --latest 50 --number 20 --sort age --save /etc/pacman.d/mirrorlist" - case "Fedora" + case "fedora" alias dmenu='wofi --dmenu' abbr --add vi "nvim" abbr --add upd "sudo dnf upgrade" @@ -194,10 +197,10 @@ if status is-interactive exec Hyprland end - case "macOS" + case "macos" abbr --add ca bat --color=always alias cat='bat -p --color=always' - case "Linuxmint" + case "linuxmint" abbr --add ca batcat --color=always alias cat='batcat -p --color=always' abbr --add upd "sudo apt update && sudo apt upgrade -y" diff --git a/.config/kitty/quick-access-terminal.conf b/.config/kitty/quick-access-terminal.conf new file mode 100644 index 00000000..ba2af3c9 --- /dev/null +++ b/.config/kitty/quick-access-terminal.conf @@ -0,0 +1,8 @@ +edge none +# 50% width on a 2560 wide screen = 1280px +columns 1100px +# 66% height on a 1600 tall screen = 1056px +lines 628px + +background_opacity 0.75 +kitty_override window_border_width=0 diff --git a/.config/kitty/ssh.conf b/.config/kitty/ssh.conf new file mode 100644 index 00000000..203407f8 --- /dev/null +++ b/.config/kitty/ssh.conf @@ -0,0 +1,3 @@ +hostname * +forward_remote_control yes + diff --git a/.config/nsxiv/exec/key-handler b/.config/nsxiv/exec/key-handler new file mode 100755 index 00000000..1852683a --- /dev/null +++ b/.config/nsxiv/exec/key-handler @@ -0,0 +1,33 @@ +#!/bin/sh +case "$1" in + "c") + # Copy file to directory + while read -r file; do + cp "$file" ~/Downloads/pictures + done + notify-send "Copied to ~/Downloads/pictures" + ;; + "y") + # Yank image data to clipboard + notify-send "Copied to clipboard" + while read -r file; do + xclip -selection clipboard -t image/png -i "$file" & + done + ;; + "e") + # Open in GIMP + notify-send "Opening Gimp" + while read -r file; do + $HOME/apps/Gimp.AppImage "$file" & + # gimp "$file" & + done + ;; + "m") + # Move file + notify-send "Moved to ~/Downloads/pictures" + while read -r file; do + mv "$file" ~/Downloads/pictures + done + ;; +esac + diff --git a/.config/xonsh/rc.d/00_rc.py b/.config/xonsh/rc.d/00_rc.py index c8c024a0..00d07e72 100644 --- a/.config/xonsh/rc.d/00_rc.py +++ b/.config/xonsh/rc.d/00_rc.py @@ -128,17 +128,19 @@ def isDistrobox(): system = platform.system() if system == "Darwin": - OS_NAME = subprocess.check_output( - ["sw_vers", "-productName"], text=True - ).strip() + OS_NAME = "macos" else: + OS_NAME = system.lower() try: - OS_NAME = subprocess.check_output( - ["lsb_release", "-is"], text=True - ).strip() - except Exception: - OS_NAME = system - + with open("/etc/os-release", "r") as f: + for line in f: + if line.startswith("ID="): + # Strip 'ID=', then strip quotes and whitespace + OS_NAME = line.split("=", 1)[1].strip().strip('"').strip("'").lower() + break + except FileNotFoundError: + pass + __xonsh__.env['OS_NAME'] = OS_NAME # -------------------------------------------------------- diff --git a/.config/xonsh/rc.d/21_aliases_os.py b/.config/xonsh/rc.d/21_aliases_os.py index 946d31ca..3946badf 100644 --- a/.config/xonsh/rc.d/21_aliases_os.py +++ b/.config/xonsh/rc.d/21_aliases_os.py @@ -27,7 +27,7 @@ archUpdateCmd += " && sudo flatpak update --assumeyes" - if OS_NAME == "Arch": + if OS_NAME == "arch": abbrevs["ca"] = "bat --color=always" abbrevs["upd"] = archUpdateCmd aliases["cat"] = "bat -p --color=always" @@ -45,12 +45,12 @@ "mirrora": "sudo reflector --latest 50 --number 20 --sort age --save /etc/pacman.d/mirrorlist", }) - elif OS_NAME == "Ubuntu": + elif OS_NAME == "ubuntu": abbrevs["ca"] = "batcat --color=always" abbrevs["upd"] = debUpdateCmd aliases["cat"] = "batcat -p --color=always" - elif OS_NAME == "Fedora": + elif OS_NAME == "fedora": abbrevs["vi"] = "nvim" abbrevs["upd"] = "sudo dnf upgrade" @@ -61,11 +61,11 @@ except Exception: pass - elif OS_NAME == "macOS": + elif OS_NAME == "macos": abbrevs["ca"] = "bat --color=always" aliases["cat"] = "bat -p --color=always" - elif OS_NAME == "Linuxmint": + elif OS_NAME == "linuxmint": abbrevs["ca"] = "batcat --color=always" abbrevs["upd"] = debUpdateCmd aliases["cat"] = "batcat -p --color=always" diff --git a/.local/bin/distrobox-app-example b/.local/bin/distrobox-app-example index 9efaf675..fee242e4 100755 --- a/.local/bin/distrobox-app-example +++ b/.local/bin/distrobox-app-example @@ -1,6 +1,6 @@ -#!/bin/bash +#!/usr/bin/env bash if [ -x "/bin/full/path/of/executable" ]; then - . /bin/full/path/of/executable + exec /bin/full/path/of/executable "$@" else /usr/bin/distrobox enter container-name -- application "$@" fi diff --git a/.local/bin/nsxiv-dir b/.local/bin/nsxiv-dir new file mode 100755 index 00000000..7061e19c --- /dev/null +++ b/.local/bin/nsxiv-dir @@ -0,0 +1,49 @@ +#!/bin/sh +set -u + +# Graceful failure if no arguments are provided +if [ "$#" -eq 0 ]; then + printf "Usage: %s \n" "$0" >&2 + exit 1 +fi + +if [ -f "$1" ]; then + dir="$(cd "$(dirname "$1")" && pwd)" + target="$dir/$(basename "$1")" + + # Include regular files AND symlinks; null-separated for safety. + # Pipe directly to nsxiv -i -0 (stdin + null separator) to avoid xargs ARG_MAX limits. + find "$dir" -maxdepth 1 \( -type f -o -type l \) -print0 | sort -z | \ + awk -v RS='\0' -v ORS='\0' -v file="$target" ' + $0 == file { print; found = 1; next } + found { print } + { before[++count] = $0 } + END { + # Fallback: if find missed the target, print it first anyway + if (!found) print file + for (i = 1; i <= count; i++) print before[i] + } + ' | nsxiv -i -0 + +elif [ -d "$1" ]; then + # Replace shell process with nsxiv + exec nsxiv "$1" +else + # Fallback for direct arguments or weird paths + exec nsxiv "$@" +fi + + +# SIMPLE: +# #!/bin/sh +# +# if [ -f "$1" ]; then +# dir="$(dirname "$1")" +# exec nsxiv "$1" "$dir" +# elif [ -d "$1" ]; then +# # If it's already a directory, just open it +# exec nsxiv "$1" +# else +# exec nsxiv "$@" +# fi + diff --git a/.local/bin/picard b/.local/bin/picard new file mode 100755 index 00000000..8bfbda07 --- /dev/null +++ b/.local/bin/picard @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +if [ -x "/usr/bin/picard" ]; then + exec /usr/bin/picard "$@" +else + /usr/bin/distrobox enter music-arch -- picard "$@" +fi + diff --git a/scripts/shell_common/brightnessctl.sh b/scripts/wm_common/brightnessctl.sh similarity index 100% rename from scripts/shell_common/brightnessctl.sh rename to scripts/wm_common/brightnessctl.sh diff --git a/scripts/wm_common/notify-debounced.sh b/scripts/wm_common/notify-debounced.sh new file mode 100755 index 00000000..d44c73ce --- /dev/null +++ b/scripts/wm_common/notify-debounced.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# Use /run/user/$UID for PID files instead of /tmp +PID_DIR="/run/user/$(id -u)" +if [[ ! -d "$PID_DIR" ]]; then + # Fallback to ~/.local/run if /run/user is not available + PID_DIR="$HOME/.local/run" + mkdir -p "$PID_DIR" +fi +DEBOUNCE_PID_FILE="$PID_DIR/debounce_notify.pid" + +# Usage: debounce_notify "" +# WARNING: Uses eval. Ensure is strictly controlled, +# as eval with untrusted input leads to command injection. +debounce_notify() { + local delay="$1" + local cmdString="$2" + + # Kill any pending notification process + if [[ -f "$DEBOUNCE_PID_FILE" ]]; then + local prevPid + prevPid=$(cat "$DEBOUNCE_PID_FILE" 2>/dev/null) + if [[ -n "$prevPid" ]] && kill -0 "$prevPid" 2>/dev/null; then + kill "$prevPid" 2>/dev/null + # No wait needed. The previous script has already exited, + # so the subshell was reparented to init, which reaps it. + fi + fi + + # Fork a background subshell that waits, evals the command, and cleans up + ( + sleep "$delay" + eval "$cmdString" + rm -f "$DEBOUNCE_PID_FILE" # Clean up PID file after execution + ) & + + local subPid=$! + + # Detach the background job so it doesn't receive SIGHUP + # when the parent script exits. + disown "$subPid" 2>/dev/null + + # Store the PID of the subshell + echo "$subPid" > "$DEBOUNCE_PID_FILE" +} + diff --git a/scripts/wm_common/volume.sh b/scripts/wm_common/volume.sh index be240175..08093306 100755 --- a/scripts/wm_common/volume.sh +++ b/scripts/wm_common/volume.sh @@ -1,5 +1,8 @@ #!/bin/bash +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/notify-debounced.sh" + #iDIR="$HOME/.config/mako/icons" iDIR="$HOME/scripts/wm_common/icons/notifications" @@ -35,14 +38,15 @@ notify_user() { if [[ "$NOTIFY_CMD" == "dunstify" ]]; then dunstify -r 9991 -u low -i "$(get_icon)" "Volume : $(get_volume) %" else - notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$(get_icon)" "Volume : $(get_volume) %" + debounce_notify 0.3 "notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i \"\$(get_icon)\" \"Volume : \$(get_volume) %\"" + #notify-send -h string:x-canonical-private-synchronous:sys-notify -u low -i "$(get_icon)" "Volume : $(get_volume) %" fi } # Increase Volume inc_volume() { if command -v pamixer &>/dev/null; then - pamixer --increase 1 && notify_user + pamixer --increase 4 && notify_user elif command -v amixer &>/dev/null; then amixer -D pulse sset Master 2%+ && notify_user else @@ -55,7 +59,7 @@ inc_volume() { # Decrease Volume dec_volume() { if command -v pamixer &>/dev/null; then - pamixer --decrease 1 && notify_user + pamixer --decrease 4 && notify_user elif command -v amixer &>/dev/null; then amixer -D pulse sset Master 2%- && notify_user else