diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-18 11:42:52 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-18 11:42:52 +0200 |
| commit | 1d527c4e47514540541abf57aa1adb6a14ae5b54 (patch) | |
| tree | dde8c34cd5e7f25291962d5a6e1bca5ac6631b5d /bin | |
| download | rofi-scripts-1d527c4e47514540541abf57aa1adb6a14ae5b54.tar.gz rofi-scripts-1d527c4e47514540541abf57aa1adb6a14ae5b54.zip | |
Initial commit: rofi-scripts, the scripts behind the rofi menus
Power menu, launcher, screenshot picker, SSH host cards, pass browser,
emoji picker, Firefox profile picker, notification actions and an
sd-server model picker. install.sh symlinks them into ~/bin; their
layouts come from unified-desktop-theme.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/blackpearl-emoji.sh | 19 | ||||
| -rwxr-xr-x | bin/blackpearl-sshmenu.sh | 40 | ||||
| -rwxr-xr-x | bin/firefox-profile | 48 | ||||
| -rwxr-xr-x | bin/notify-actions.sh | 41 | ||||
| -rwxr-xr-x | bin/qar-scrotmenu.sh | 34 | ||||
| -rwxr-xr-x | bin/rofipass | 351 | ||||
| -rwxr-xr-x | bin/sd-webui | 86 | ||||
| -rwxr-xr-x | bin/udt-launcher.sh | 22 | ||||
| -rwxr-xr-x | bin/udt-powermenu.sh | 96 |
9 files changed, 737 insertions, 0 deletions
diff --git a/bin/blackpearl-emoji.sh b/bin/blackpearl-emoji.sh new file mode 100755 index 0000000..3969c43 --- /dev/null +++ b/bin/blackpearl-emoji.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# blackpearl-emoji.sh - emoji picker, rofi themed by udt +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +rofi -no-lazy-grab -modi emoji -show emoji -display-emoji ' Emoji:' -theme ~/.config/rofi/udt/grid.rasi + diff --git a/bin/blackpearl-sshmenu.sh b/bin/blackpearl-sshmenu.sh new file mode 100755 index 0000000..b0a0fc1 --- /dev/null +++ b/bin/blackpearl-sshmenu.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# blackpearl-sshmenu.sh - the hosts in ~/.ssh/config as rofi cards +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# rofi's own ssh mode shows the alias only, so the config is read here. +# ponytail: plain "Keyword value" lines in ~/.ssh/config only; Include and +# Match are not followed, wildcard Host patterns are skipped. +mapfile -t hosts < <(awk ' + function flush() { if (name != "") print name "\t" user "\t" addr } + tolower($1) == "host" { flush(); name = ($2 ~ /[*?]/) ? "" : $2; user = ""; addr = $2 } + tolower($1) == "hostname" { addr = $2 } + tolower($1) == "user" { user = $2 } + END { flush() }' ~/.ssh/config) + +# Two lines a card: the alias, then "user · address" with the user only where +# the config sets one. Entries are joined on "|" so each can hold a newline. +entries=() +for h in "${hosts[@]}"; do + IFS=$'\t' read -r name user addr <<< "$h" + entries+=("<b>$name</b> +<span size='small' fgalpha='65%'>${user:+$user · }$addr</span>") +done + +i=$(IFS='|'; printf '%s' "${entries[*]}" | rofi -dmenu -i -markup-rows \ + -sep '|' -eh 2 -format i -p ' SSH:' -theme ~/.config/rofi/udt/ssh.rasi) || exit +name=${hosts[i]%%$'\t'*} +exec rofi-sensible-terminal -e ssh "$name" diff --git a/bin/firefox-profile b/bin/firefox-profile new file mode 100755 index 0000000..3920e09 --- /dev/null +++ b/bin/firefox-profile @@ -0,0 +1,48 @@ +#!/bin/bash +# firefox-profile - pick a Firefox profile with rofi, one behind a password +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Pick a Firefox profile with rofi; one profile requires a password. +# Hash file: printf '%s' 'secret' | sha256sum | cut -d' ' -f1 > ~/.config/firefox-profile.hash +# ponytail: wrapper gate only, `firefox -P <name>` bypasses it. Encrypt the profile dir if that matters. + +PROTECTED="danix" +HASHFILE="$HOME/.config/firefox-profile.hash" +INI="$HOME/.mozilla/firefox/profiles.ini" + +# Opening a link with exactly one profile running: hand it to that instance, +# no picker. The protected profile was already unlocked to get it running. +if [ $# -gt 0 ]; then + running=$(pgrep -af '^/usr/lib64/firefox/firefox(-bin)? (.* )?-P ' | sed -n 's/.* -P \([^ ]*\).*/\1/p' | sort -u) + [ -n "$running" ] && [ "$(wc -l <<<"$running")" -eq 1 ] && exec firefox -P "$running" "$@" +fi + +profile=$(sed -n 's/^Name=//p' "$INI" | rofi -dmenu -theme ~/.config/rofi/udt/list.rasi -i -p ' Firefox:') || exit 0 +[ -n "$profile" ] || exit 0 + +if [ "$profile" = "$PROTECTED" ]; then + pass=$(rofi -dmenu -theme ~/.config/rofi/udt/list.rasi -password -l 0 \ + -mesg "Unlock Firefox profile: $profile" \ + -theme-str 'mainbox { children: [ message, inputbar ]; padding: 16px; spacing: 8px; } message { background-color: transparent; padding: 0 0 4px 2px; } textbox { font: "Noto Sans Bold 13"; }' \ + -theme-str 'entry { placeholder: "Password"; }' </dev/null) || exit 0 + hash=$(printf '%s' "$pass" | sha256sum | cut -d' ' -f1) + if [ "$hash" != "$(cat "$HASHFILE" 2>/dev/null)" ]; then + notify-send "Firefox" "Wrong password" 2>/dev/null + exit 1 + fi +fi + +exec firefox -P "$profile" "$@" diff --git a/bin/notify-actions.sh b/bin/notify-actions.sh new file mode 100755 index 0000000..0c49c6b --- /dev/null +++ b/bin/notify-actions.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# Pick one of a notification's actions with rofi and invoke it. The renderer +# passes the labels and keys as arguments, so nothing here parses JSON. +# +# notify-actions.sh <id> <label> <key> [label key ...] + +set -u + +[[ $# -ge 3 ]] || { echo "usage: ${0##*/} <id> <label> <key> ..." >&2; exit 2; } + +id="$1"; shift +labels=() +keys=() +while [[ $# -ge 2 ]]; do + labels+=("$1") + keys+=("$2") + shift 2 +done + +choice="$(printf '%s\n' "${labels[@]}" | rofi -dmenu -i -p "Notification" \ + -theme "$HOME/.config/rofi/udt/menu.rasi")" +[[ -n "$choice" ]] || exit 0 + +for i in "${!labels[@]}"; do + if [[ "${labels[$i]}" == "$choice" ]]; then + notifyctl action "$id" "${keys[$i]}" + exit $? + fi +done diff --git a/bin/qar-scrotmenu.sh b/bin/qar-scrotmenu.sh new file mode 100755 index 0000000..2b7341f --- /dev/null +++ b/bin/qar-scrotmenu.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# qar-scrotmenu.sh - screenshot menu, rofi themed by udt +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +rofi_command=(rofi -theme ~/.config/rofi/udt/screenshot.rasi) + +### Options ### +screen="" +area="" +# Variable passed to rofi +options="$screen\n$area" + +chosen="$(echo -e "$options" | "${rofi_command[@]}" -dmenu -selected-row 1 -p ' Screenshot:')" +case $chosen in + $screen) + grimblast -w 3 -n -t png copysave active + ;; + $area) + grimblast -n -t png copysave area + ;; +esac diff --git a/bin/rofipass b/bin/rofipass new file mode 100755 index 0000000..b9620f8 --- /dev/null +++ b/bin/rofipass @@ -0,0 +1,351 @@ +#!/usr/bin/env sh +# rofipass - rofi front end for pass +# +# Derived from rofipass by Augusto Coronel (https://github.com/aocoronel/rofipass), +# released under the MIT License, whose notice is kept below as it requires. +# Modifications Copyright (C) 2026 Danilo M. <danix@danix.xyz>, released under +# the GNU General Public License version 2 (see LICENSE). +# +# MIT License +# +# Copyright (c) 2025 Augusto Coronel +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +### Colors + +help_color="#7c5cff" +div_color="#334433" +label="#f067fc" + +### + +### Bindings + +kb_copy_email="Ctrl+2" # EMAIL +kb_copy_otp="Ctrl-1" # COPY TOTP +kb_add_pass="Ctrl+r" # PASSWORD +kb_add_otp="Ctrl+t" # ADD TOTP +kb_delete="Ctrl-x" # DELETE +kb_edit="Ctrl+y" # EDIT +kb_close_tomb="Ctrl-z" # CLOSE TOMB +kb_open_tomb="Ctrl-o" # OPEN TOMB + +### + +clipmethod="$XDG_SESSION_TYPE" +passdir=${PASSWORD_STORE_DIR:-$HOME/.password-store} + +COLOR_YELLOW="$(tput setaf 226)" +COLOR_RED="$(tput setaf 196)" +COLOR_GREEN="$(tput setaf 82)" +COLOR_BLUE="$(tput setaf 87)" +COLOR_RESET=$(tput sgr0) + +printfc() { + mode=$1 + case $mode in + "ERROR" | "FATAL") + color="$COLOR_RED" + ;; + "WARN") + mode="WARNING" + color="$COLOR_YELLOW" + ;; + "DEBUG") + color="$COLOR_BLUE" + ;; + "INFO") + color="$COLOR_GREEN" + ;; + esac + text=$2 + printf "%s[%s]:%s %s\n" "${color}" "${mode}" "${COLOR_RESET}" "${text}" +} + +check_command() { + for cmd in "$@"; do + if ! command -v "$cmd" >/dev/null 2>&1; then + printfc FATAL "$cmd is not installed." + return 1 + fi + done +} + +_notify() { + message="$1" + header="rofipass" + urgency="$2" + time=${3:-$time} + echo "$message" + if [ "$time" -eq 0 ]; then + notify-send -u "$urgency" "$header" "$message" + else + notify-send -u "$urgency" "$header" "$message" --expire-time="$time"000 --wait + fi +} + +die() { + mode=$1 + message=$2 + urgency=$3 + + printfc "$mode" "$message" + _notify "$message" "$urgency" + exit 1 +} + +version() { + echo "v1.1.0" +} + +usage() { + cat <<EOF +rofipass | A rofi extension for pass + +Usage: rofipass [OPTIONS] <COMMAND> + +Options: + -e <EDITOR> Set editor + -f Lift swap restrictions (for tomb) + -h Display this help message and exit + -l <LENGTH> Default password length on generation + -t <TERM> Default terminal emulator (for tomb) + -v Display the current version number + -T <SECONDS> Clearing time + +Example: + rofipass -f -l 72 -t kitty -e nvim -T 10 +EOF +} + +_rofi() { + rofi -dmenu -theme ~/.config/rofi/udt/list.rasi -i -no-levenshtein-sort "$@" +} + +copy_email() { + email=$(pass "$menu" | sed -n 's/^email=//p') + case "$clipmethod" in + "x11") + xclip "$email" || die FATAL "failed to copy the email." "critical" + _notify "Copied to clipboard. Clearing in $time seconds" "normal" + ;; + "wayland") + wl-copy "$email" || die FATAL "failed to copy the email." "critical" + _notify "Copied to clipboard. Clearing in $time seconds" "normal" + ;; + esac + # clearboard +} + +append_otp() { + check_command zbarimg || die FATAL "zbarimg is not installed." "critical" + case "$clipmethod" in + "x11") + xclip -o | zbarimg -q --raw - | pass otp append "$menu" || die FATAL "failed to append OTP to $menu" "critical" + _notify "Inserted OTP successfully to $menu" "normal" + ;; + "wayland") + wl-paste --type image/png | zbarimg -q --raw - | pass otp append "$menu" || die FATAL "failed to append OTP to $menu" "critical" + _notify "Inserted OTP successfully to $menu" "normal" + ;; + esac +} + +clearboard() { + [ -x "$(command -v notifyctl)" ] && notifyctl close-all + + case "$clipmethod" in + "x11") + echo "" | xclip -sel clip + ;; + "wayland") + [ -x "$(command -v cliphist)" ] && cliphist wipe + echo "" | wl-copy + ;; + esac +} + +tomb_open() { + if [ -n "$FORCE" ]; then + $term -e sh -c "pass open -f" + else + $term -e sh -c "pass open" + fi +} + +tomb_close() { + $term -e sh -c "pass close" + pass_val=$? + if [ "$pass_val" -ne 0 ]; then + die FATAL "failed to close tomb." -u "critical" + else + _notify "Your password tomb has been closed!" "normal" 0 + fi +} + +deleteMenu() { + delask=$(printf "1. Yes\n2. No" | _rofi -p ' Delete:' -mesg "<span color='${label}'>Really delete</span> <span color='${help_color}'>$menu?</span>") + val=$? + [ $val -eq 1 ] && { + _notify "Cancelled!" "low" 0 + main + } + [ "$delask" = "1. Yes" ] && pass rm -f "$menu" && _notify "Deleted $menu" "normal" 0 + main +} + +add_password() { + length=${length:-72} + addmenu=$( + echo | _rofi -p ' New password:' -lines 0 \ + -theme-str 'window { width: 25em; } listview { lines: 0; } entry { placeholder: "Enter password name"; }' + ) + val=$? + if [ $val -eq 1 ]; then + _notify "Cancelled!" "low" 0 + main + elif [ $val -eq 0 ]; then + if command -v "passgen.py" >/dev/null 2>&1; then + passgen.py 3 | pass insert -e "$addmenu" + else + pass generate "$addmenu" "$length" + fi + if [ $val -eq 1 ]; then + _notify ERROR "failed to add password" 0 + main + else + _notify "Added $addmenu" "normal" 0 + fi + fi + main +} + +edit_password() { + $term -e sh -c "export EDITOR=\"$editor\"; pass edit \"$menu\"" +} + +main() { + enable_tomb=0 + enable_otp=0 + enable_zbar=0 + + if ! command -v "tomb" >/dev/null 2>&1; then + enable_tomb=1 + fi + if ! command -v "zbarimg" >/dev/null 2>&1; then + enable_zbar=1 + fi + + pass otp -h >/dev/null 2>&1 || enable_otp=1 + + HELP="" + + HELP="$HELP<span color='${label}'>Actions: </span><span color='${help_color}'>${kb_add_pass}</span>: Add <span color='${div_color}'>|</span> <span color='${help_color}'>${kb_delete}</span>: Delete <span color='${div_color}'>|</span> <span color='${help_color}'>${kb_edit}</span>: Edit" + + if [ "$enable_zbar" -eq 0 ]; then + ZBAR_HELP=" <span color='${div_color}'>|</span> <span color='${help_color}'>${kb_add_otp}</span>: Add OTP" + HELP="$HELP$ZBAR_HELP" + fi + + HELP="$HELP +<span color='${label}'>Copy: </span><span color='${help_color}'>Enter</span>: Copy Password <span color='${div_color}'>|</span> <span color='${help_color}'>${kb_copy_email}</span>: Copy Email" + + if [ "$enable_otp" -eq 0 ]; then + OTP_HELP=" <span color='${div_color}'>|</span> <span color='${help_color}'>${kb_copy_otp}</span>: Copy OTP" + HELP="$HELP$OTP_HELP" + fi + + if [ "$enable_tomb" -eq 0 ]; then + TOMB_HELP="<span color='${label}'>Tomb: </span><span color='${help_color}'>${kb_close_tomb}</span>: Close Tomb <span color='${div_color}'>|</span> <span color='${help_color}'>${kb_open_tomb}</span>: Open Tomb" + HELP="$HELP +$TOMB_HELP" + fi + + pass=$(find -L "$passdir" -type f -name '*.gpg' -printf '%P\n' | sed 's/\.gpg//') + menu=$(echo "${pass}" | _rofi -p ' Pass:' -mesg "${HELP}" -kb-custom-1 "${kb_add_pass}" -kb-custom-2 "${kb_copy_otp}" -kb-custom-3 "${kb_delete}" -kb-custom-4 "${kb_edit}" -kb-custom-5 "${kb_close_tomb}" -kb-custom-6 "${kb_open_tomb}" -kb-custom-7 "${kb_copy_email}" -kb-custom-8 "${kb_add_otp}") + + val=$? + case "$val" in + 1) exit ;; + 12) deleteMenu ;; + 11) # OTP Copy + [ "$enable_otp" -eq 0 ] && { + timeout 3 pass otp -c "$menu" || die ERROR "failed to copy OTP!" "normal" + _notify "Copied to clipboard. Clearing in $time seconds" "normal" + # clearboard + } + ;; + 10) add_password ;; + 13) edit_password ;; + 14) [ "$enable_tomb" -eq 0 ] && tomb_close ;; + 15) [ "$enable_tomb" -eq 0 ] && tomb_open ;; + 16) copy_email ;; + 17) [ "$enable_zbar" -eq 0 ] && append_otp ;; + 0) + pass -c "$menu" || die ERROR "failed to copy the password!" "normal" + _notify "Copied to clipboard. Clearing in $time seconds" "normal" + # clearboard + ;; + esac +} + +while getopts ":hvfl:t:T:e:" opt; do + case "$opt" in + h) + usage + exit 0 + ;; + e) + editor="$OPTARG" + ;; + v) + version + exit 0 + ;; + f) + FORCE=true + ;; + l) + length="$OPTARG" + ;; + t) + term="$OPTARG" + ;; + T) + time="$OPTARG" + ;; + ?) + printfc FATAL "invalid option '-$OPTARG'" >&2 + exit 1 + ;; + esac +done + +shift $((OPTIND - 1)) + +check_command rofi pass || exit 1 + +[ ! -d "$passdir" ] && die FATAL "no password directory found!" "low" + +[ -z "$editor" ] && editor=${EDITOR:-nano} +term=${term:-kitty} +time=${time:-5} + +main diff --git a/bin/sd-webui b/bin/sd-webui new file mode 100755 index 0000000..0d72547 --- /dev/null +++ b/bin/sd-webui @@ -0,0 +1,86 @@ +#!/bin/bash +# sd-webui - start sd-server with a model picked from rofi +# Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Start sd-server (stable-diffusion.cpp) with a model picked from rofi and open its web UI. +# Runs in the foreground: close the terminal (or Ctrl-C) to stop it and free VRAM. + +M=/data/LLM-models/SD +QWEN=(--llm $M/Qwen3VL-8B-Instruct-Q8_0.gguf + --llm_vision $M/mmproj-Qwen3VL-8B-Instruct-F16.gguf + --vae $M/vae/qwen_image_2.1_vae_bf16.safetensors) +SDXL=(--cfg-scale 7.0 --steps 25) # same defaults as imggen + +# Pick the model (sd-server loads one per process, so choose at start). +case $(printf '%s\n' \ + "Qwen Image 2.1 (base, 20 steps, text/edit/RGBA)" \ + "Qwen Image 2.1 turbo (6 steps)" \ + "Z-Image Turbo (8 steps, photoreal)" \ + "FLUX.2 klein 4B (4 steps, edit)" \ + "Krea 2 Turbo (8 steps, photoreal)" \ + "Wan2.2 TI2V 5B (video, text/image)" \ + "SDXL base" \ + "RealVisXL V5" \ + "Pony Diffusion V6 XL" \ + | rofi -dmenu -i -theme ~/.config/rofi/udt/list.rasi -p ' SD model:' \ + -theme-str 'entry { placeholder: "Search models"; }') in + "Qwen Image 2.1 (base"*) MODEL=(--diffusion-model $M/qwen_image_2.1-Q8_0.gguf "${QWEN[@]}" + --cfg-scale 6.0 --cache-mode cache-dit) ;; + "Qwen Image 2.1 turbo"*) MODEL=(--diffusion-model $M/Qwen-Image-2.1-viggle-turbo-v0.3-6step-Q8_0.gguf "${QWEN[@]}" + --cfg-scale 1.0 --steps 6) ;; + Z-Image*) MODEL=(--diffusion-model $M/z_image_turbo-Q8_0.gguf + --llm $M/Qwen3-4B-Instruct-2507-Q8_0.gguf --vae $M/vae/flux1-ae.safetensors + --cfg-scale 1.0 --steps 8 --diffusion-fa) ;; + FLUX.2*) MODEL=(--diffusion-model $M/flux-2-klein-4b-Q8_0.gguf + --llm $M/Qwen3-4B-Q8_0.gguf --vae $M/vae/flux2-vae.safetensors + --cfg-scale 1.0 --steps 4 --diffusion-fa) ;; + # Q6_K: same output as Q8_0 at seed 42, ~20% faster (both still offload on 12G). + Krea*) MODEL=(--diffusion-model $M/Krea-2-Turbo-Q6_K.gguf + --llm $M/Qwen3VL-4B-Instruct-Q8_0.gguf --vae $M/vae/wan_2.1_vae.safetensors + --cfg-scale 1.0 --steps 8 --diffusion-fa) ;; + # 1280x704 is the model's native 720p. Frames must be 4k+1 at 24 fps: 49 = 2 s, 121 = 5 s. + # Settings follow upstream Wan2.2 5B defaults (cfg 5, shift 5); drop to 832x480 if too slow. + Wan2.2*) MODEL=(--diffusion-model $M/Wan2.2-TI2V-5B-Q8_0.gguf + --t5xxl $M/umt5-xxl-encoder-Q8_0.gguf --vae $M/vae/wan2.2_vae.safetensors + --cfg-scale 5.0 --steps 30 --flow-shift 5.0 --diffusion-fa + -W 1280 -H 704 --video-frames 49 --temporal-tiling) ;; + # imggen's diffusers weights, symlinked into the layout sd.cpp loads as a directory + "SDXL base") MODEL=(-m $M/sdxl-links/sdxl "${SDXL[@]}") ;; + RealVisXL*) MODEL=(-m $M/sdxl-links/realvis "${SDXL[@]}") ;; + Pony*) MODEL=(-m $M/sdxl-links/pony "${SDXL[@]}" --clip-skip 2) ;; + *) exit 0 ;; +esac + +PORT=${PORT:-7860} +URL=http://127.0.0.1:$PORT/ + +# Open the browser once the server answers (model loading takes a while). +( + until curl -sf -o /dev/null "$URL"; do sleep 1; done + notify-send -a sd-server -i applications-graphics "Stable Diffusion server started" "$URL" + xdg-open "$URL" >/dev/null 2>&1 +) & +trap 'kill $! 2>/dev/null' EXIT + +# Log to a file too: the terminal loses the output when the server crashes. +# stdbuf -oL: line-buffer stdout so the last lines before a crash reach the log. +LOG=${XDG_CACHE_HOME:-$HOME/.cache}/sd-server.log +# MODEL goes after the shared defaults so a model can override them (e.g. Wan's -W/-H). +stdbuf -oL -eL sd-server --listen-port "$PORT" \ + --lora-model-dir $M/loras \ + --sampling-method euler -W 1024 -H 1024 --seed -1 \ + "${MODEL[@]}" \ + --offload-to-cpu -v "$@" 2>&1 | tee "$LOG" diff --git a/bin/udt-launcher.sh b/bin/udt-launcher.sh new file mode 100755 index 0000000..d0a8013 --- /dev/null +++ b/bin/udt-launcher.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +## Author : Aditya Shakya (adi1090x) +## Github : @adi1090x +## Derived from adi1090x/rofi, GPL-3.0 like upstream. Modifications +## Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +## Rofi : Launcher (Modi Drun, Run, File Browser, Window) +# +## Available Styles +# +## style-1 style-2 style-3 style-4 style-5 +## style-6 style-7 style-8 style-9 style-10 +## style-11 style-12 style-13 style-14 style-15 + +dir="$HOME/.config/rofi/udt" +theme='launcher' + +## Run +rofi \ + -show drun \ + -theme ${dir}/${theme}.rasi diff --git a/bin/udt-powermenu.sh b/bin/udt-powermenu.sh new file mode 100755 index 0000000..6d8fb84 --- /dev/null +++ b/bin/udt-powermenu.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + +## Author : Aditya Shakya (adi1090x) +## Github : @adi1090x +## Derived from adi1090x/rofi, GPL-3.0 like upstream. Modifications +## Copyright (C) 2026 Danilo M. <danix@danix.xyz> +# +## Rofi : Power Menu +# +## Available Styles +# +## style-1 style-2 style-3 style-4 style-5 + +# Current Theme +dir="$HOME/.config/rofi/udt" +theme='powermenu' + +# CMDs +uptime="`uptime -p | sed -e 's/up //g'`" +host=`hostname` + +# Options +shutdown='' +reboot='' +logout='' +sleep='' +yes='' +no='' + +# Rofi CMD +rofi_cmd() { + rofi -dmenu \ + -p "'ndi vidimu ${USER}" \ + -mesg "Uptime: $uptime" \ + -theme ${dir}/${theme}.rasi +} + +# Confirmation CMD +confirm_cmd() { + rofi -dmenu \ + -p 'Confirmation' \ + -selected-row 1 \ + -mesg 'Simu Sicuri?' \ + -theme "$HOME/.config/rofi/udt/confirm.rasi" +} + +# Ask for confirmation +confirm_exit() { + echo -e "$yes\n$no" | confirm_cmd +} + +# Pass variables to rofi dmenu +run_rofi() { + echo -e "$shutdown\n$reboot\n$sleep\n$logout" | rofi_cmd +} + +# Execute Command +run_cmd() { + selected="$(confirm_exit)" + if [[ "$selected" == "$yes" ]]; then + if [[ $1 == '--shutdown' ]]; then + notify-send 'system shutdown' 'the system is going to shutdown now' + sleep 1 + /usr/bin/loginctl poweroff + elif [[ $1 == '--reboot' ]]; then + notify-send 'system reboot' 'the system is going to reboot now' + sleep 1 + /usr/bin/loginctl reboot + elif [[ $1 == '--sleep' ]]; then + notify-send 'suspend to ram' 'the system is going to sleep now' + sleep 1 + /usr/bin/loginctl suspend + elif [[ $1 == '--logout' ]]; then + hyprctl dispatch 'hl.dsp.exit()' + fi + else + exit 0 + fi +} + +# Actions +chosen="$(run_rofi)" +case ${chosen} in + $shutdown) + run_cmd --shutdown + ;; + $reboot) + run_cmd --reboot + ;; + $sleep) + run_cmd --sleep + ;; + $logout) + run_cmd --logout + ;; +esac |
