mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-01 20:28:16 +02:00
Add a simple way to set the screensaver to an ascii version of an image
This commit is contained in:
@@ -55,6 +55,7 @@ GROUP_DESCRIPTIONS[reinstall]="Reinstall and reset workflows"
|
||||
GROUP_DESCRIPTIONS[remove]="Removal workflows"
|
||||
GROUP_DESCRIPTIONS[restart]="Restart Omarchy components"
|
||||
GROUP_DESCRIPTIONS[setup]="Interactive setup wizards"
|
||||
GROUP_DESCRIPTIONS[screensaver]="Screensaver branding and animation"
|
||||
GROUP_DESCRIPTIONS[snapshot]="System snapshots"
|
||||
GROUP_DESCRIPTIONS[state]="Persistent Omarchy state"
|
||||
GROUP_DESCRIPTIONS[sudo]="Sudo configuration helpers"
|
||||
|
||||
+25
-1
@@ -217,12 +217,36 @@ show_style_menu() {
|
||||
*Font*) show_font_menu ;;
|
||||
*Background*) show_background_menu ;;
|
||||
*Hyprland*) open_in_editor ~/.config/hypr/looknfeel.conf ;;
|
||||
*Screensaver*) open_in_editor ~/.config/omarchy/branding/screensaver.txt ;;
|
||||
*Screensaver*) show_screensaver_menu ;;
|
||||
*About*) open_in_editor ~/.config/omarchy/branding/about.txt ;;
|
||||
*) show_main_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
show_screensaver_menu() {
|
||||
case $(menu "Screensaver" " Set From Image\n Restore Default\n Edit Text\n Preview") in
|
||||
*Image*) set_screensaver_from_image ;;
|
||||
*Default*) terminal bash -lc 'omarchy-screensaver-set-logo default; echo; read -n 1 -s -r -p "Press any key to close..."' ;;
|
||||
*Text*) open_in_editor ~/.config/omarchy/branding/screensaver.txt ;;
|
||||
*Preview*) omarchy-launch-screensaver force ;;
|
||||
*) show_style_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
set_screensaver_from_image() {
|
||||
terminal bash -lc '
|
||||
image=$(fd --type file --ignore-case --extension svg --extension png . "$HOME" 2>/dev/null | fzf --prompt "Logo image> ")
|
||||
if [[ -n $image ]]; then
|
||||
if omarchy-screensaver-set-logo "$image"; then
|
||||
echo
|
||||
echo "Preview with: omarchy-launch-screensaver force"
|
||||
fi
|
||||
echo
|
||||
read -n 1 -s -r -p "Press any key to close..."
|
||||
fi
|
||||
'
|
||||
}
|
||||
|
||||
show_theme_menu() {
|
||||
omarchy-launch-walker -m menus:omarchythemes --width 800 --minheight 400
|
||||
}
|
||||
|
||||
Executable
+384
@@ -0,0 +1,384 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Set the screensaver logo text from an SVG/PNG or the default
|
||||
# omarchy:args=<default|path-to-logo.svg|png> [--width <columns>] [--height <rows>] [--mode <braille|block>] [--threshold <percent>] [--invert] [--stdout]
|
||||
# omarchy:examples=omarchy screensaver set logo ~/logo.svg | omarchy screensaver set logo default | omarchy screensaver set logo ~/logo.png --width 80 --mode block --stdout
|
||||
|
||||
set -o pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: omarchy-screensaver-set-logo <default|path-to-logo.svg|png> [options]
|
||||
|
||||
Sets the screensaver logo text from an image.
|
||||
Pass "default" instead of an image path to restore the Omarchy default.
|
||||
By default, writes to ~/.config/omarchy/branding/screensaver.txt.
|
||||
|
||||
Options:
|
||||
-w, --width <columns> Maximum output width in terminal columns (default: 80)
|
||||
-H, --height <rows> Maximum output height in terminal rows (default: 26)
|
||||
-m, --mode <braille|block> Output style (default: braille)
|
||||
-t, --threshold <percent> Pixel threshold from 0-100 (default: 50)
|
||||
--invert Treat light pixels as the logo instead of dark pixels
|
||||
--no-trim Preserve surrounding whitespace/background
|
||||
--stdout Print converted text instead of writing the screensaver file
|
||||
--help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
width=80
|
||||
height=26
|
||||
mode=braille
|
||||
threshold=50
|
||||
invert=false
|
||||
trim=true
|
||||
output_path="$HOME/.config/omarchy/branding/screensaver.txt"
|
||||
image_path=""
|
||||
reset_default=false
|
||||
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-w | --width)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --width" >&2
|
||||
exit 1
|
||||
fi
|
||||
width="$1"
|
||||
;;
|
||||
--width=*)
|
||||
width="${1#*=}"
|
||||
;;
|
||||
-H | --height)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --height" >&2
|
||||
exit 1
|
||||
fi
|
||||
height="$1"
|
||||
;;
|
||||
--height=*)
|
||||
height="${1#*=}"
|
||||
;;
|
||||
-m | --mode)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --mode" >&2
|
||||
exit 1
|
||||
fi
|
||||
mode="$1"
|
||||
;;
|
||||
--mode=*)
|
||||
mode="${1#*=}"
|
||||
;;
|
||||
--block | --blocks)
|
||||
mode=block
|
||||
;;
|
||||
--braille)
|
||||
mode=braille
|
||||
;;
|
||||
-t | --threshold)
|
||||
shift
|
||||
if [[ -z $1 ]]; then
|
||||
echo "Missing value for --threshold" >&2
|
||||
exit 1
|
||||
fi
|
||||
threshold="$1"
|
||||
;;
|
||||
--threshold=*)
|
||||
threshold="${1#*=}"
|
||||
;;
|
||||
--invert)
|
||||
invert=true
|
||||
;;
|
||||
--no-trim)
|
||||
trim=false
|
||||
;;
|
||||
--stdout)
|
||||
output_path="-"
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [[ $1 == "default" && -z $image_path ]]; then
|
||||
reset_default=true
|
||||
elif [[ -z $image_path ]]; then
|
||||
image_path="$1"
|
||||
else
|
||||
echo "Unexpected argument: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if (($# > 0)); then
|
||||
while (($# > 0)); do
|
||||
if [[ $1 == "default" && -z $image_path ]]; then
|
||||
reset_default=true
|
||||
elif [[ -z $image_path ]]; then
|
||||
image_path="$1"
|
||||
else
|
||||
echo "Unexpected argument: $1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ $reset_default == "true" ]]; then
|
||||
if [[ -n $image_path ]]; then
|
||||
echo "default does not accept an image path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
default_path="${OMARCHY_PATH:-$HOME/.local/share/omarchy}/logo.txt"
|
||||
if [[ ! -f $default_path ]]; then
|
||||
echo "Default screensaver logo text not found: $default_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $output_path == "-" ]]; then
|
||||
cat "$default_path"
|
||||
else
|
||||
mkdir -p "$(dirname "$output_path")"
|
||||
cp "$default_path" "$output_path"
|
||||
echo "Restored default screensaver logo text to $output_path"
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -z $image_path ]]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ $width =~ ^[0-9]+$ ]] || (( width < 1 )); then
|
||||
echo "Invalid width: $width" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ $height =~ ^[0-9]+$ ]] || (( height < 1 )); then
|
||||
echo "Invalid height: $height" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $mode != "braille" && $mode != "block" ]]; then
|
||||
echo "Invalid mode: $mode (expected braille or block)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [[ $threshold =~ ^[0-9]+$ ]] || (( threshold < 0 || threshold > 100 )); then
|
||||
echo "Invalid threshold: $threshold (expected 0-100)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f $image_path ]]; then
|
||||
echo "Logo file not found: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if omarchy-cmd-missing magick; then
|
||||
echo "ImageMagick is required to convert logo images" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$mode" in
|
||||
braille)
|
||||
pixel_width=$((width * 2))
|
||||
pixel_height=$((height * 4))
|
||||
;;
|
||||
block)
|
||||
pixel_width=$width
|
||||
pixel_height=$((height * 2))
|
||||
;;
|
||||
esac
|
||||
|
||||
alpha_min=$(magick -background none "$image_path" -alpha extract -format '%[fx:minima]' info: 2>/dev/null) || {
|
||||
echo "Unable to read logo image: $image_path" >&2
|
||||
exit 1
|
||||
}
|
||||
alpha_max=$(magick -background none "$image_path" -alpha extract -format '%[fx:maxima]' info: 2>/dev/null) || {
|
||||
echo "Unable to read logo image: $image_path" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
use_alpha=false
|
||||
if awk -v min="$alpha_min" -v max="$alpha_max" 'BEGIN { exit !(min < 0.999 && max > min) }'; then
|
||||
use_alpha=true
|
||||
fi
|
||||
|
||||
magick_args=(-background none "$image_path" -auto-orient)
|
||||
|
||||
if [[ $use_alpha == "true" ]]; then
|
||||
magick_args+=(-alpha extract -alpha off)
|
||||
if [[ $invert == "true" ]]; then
|
||||
magick_args+=(-negate)
|
||||
fi
|
||||
else
|
||||
magick_args+=(-alpha remove -alpha off -colorspace Gray)
|
||||
if [[ $invert == "false" ]]; then
|
||||
magick_args+=(-negate)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $trim == "true" ]]; then
|
||||
magick_args+=(-bordercolor black -border 1 -trim +repage)
|
||||
fi
|
||||
|
||||
magick_args+=(-resize "${pixel_width}x${pixel_height}" -threshold "${threshold}%" -negate -compress none pbm:-)
|
||||
|
||||
tmp_output=$(mktemp)
|
||||
trap 'rm -f "$tmp_output"' EXIT
|
||||
|
||||
if [[ $mode == "braille" ]]; then
|
||||
if ! magick "${magick_args[@]}" | awk '
|
||||
BEGIN {
|
||||
braille_base = 10240
|
||||
dot[0,0] = 1
|
||||
dot[0,1] = 2
|
||||
dot[0,2] = 4
|
||||
dot[1,0] = 8
|
||||
dot[1,1] = 16
|
||||
dot[1,2] = 32
|
||||
dot[0,3] = 64
|
||||
dot[1,3] = 128
|
||||
}
|
||||
{
|
||||
sub(/#.*/, "")
|
||||
for (i = 1; i <= NF; i++) {
|
||||
token[++token_count] = $i
|
||||
}
|
||||
}
|
||||
END {
|
||||
if (token[1] != "P1") {
|
||||
exit 1
|
||||
}
|
||||
|
||||
width = token[2]
|
||||
height = token[3]
|
||||
pixel_offset = 4
|
||||
|
||||
for (y = 0; y < height; y += 4) {
|
||||
line = ""
|
||||
for (x = 0; x < width; x += 2) {
|
||||
code = 0
|
||||
for (dy = 0; dy < 4; dy++) {
|
||||
for (dx = 0; dx < 2; dx++) {
|
||||
if (y + dy < height && x + dx < width) {
|
||||
pixel = token[pixel_offset + ((y + dy) * width) + x + dx]
|
||||
if (pixel == 1) {
|
||||
code += dot[dx,dy]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
line = line " "
|
||||
} else {
|
||||
line = line sprintf("%c", braille_base + code)
|
||||
}
|
||||
}
|
||||
sub(/[ ]+$/, "", line)
|
||||
lines[++line_count] = line
|
||||
}
|
||||
|
||||
first = 1
|
||||
while (first <= line_count && lines[first] ~ /^[ ]*$/) {
|
||||
first++
|
||||
}
|
||||
|
||||
last = line_count
|
||||
while (last >= first && lines[last] ~ /^[ ]*$/) {
|
||||
last--
|
||||
}
|
||||
|
||||
for (i = first; i <= last; i++) {
|
||||
print lines[i]
|
||||
}
|
||||
}
|
||||
' >"$tmp_output"; then
|
||||
echo "Unable to convert logo image: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ! magick "${magick_args[@]}" | awk '
|
||||
BEGIN {
|
||||
block["11"] = "█"
|
||||
block["10"] = "▀"
|
||||
block["01"] = "▄"
|
||||
block["00"] = " "
|
||||
}
|
||||
{
|
||||
sub(/#.*/, "")
|
||||
for (i = 1; i <= NF; i++) {
|
||||
token[++token_count] = $i
|
||||
}
|
||||
}
|
||||
END {
|
||||
if (token[1] != "P1") {
|
||||
exit 1
|
||||
}
|
||||
|
||||
width = token[2]
|
||||
height = token[3]
|
||||
pixel_offset = 4
|
||||
|
||||
for (y = 0; y < height; y += 2) {
|
||||
line = ""
|
||||
for (x = 0; x < width; x++) {
|
||||
top = token[pixel_offset + (y * width) + x]
|
||||
bottom = (y + 1 < height) ? token[pixel_offset + ((y + 1) * width) + x] : 0
|
||||
line = line block[top bottom]
|
||||
}
|
||||
sub(/[ ]+$/, "", line)
|
||||
lines[++line_count] = line
|
||||
}
|
||||
|
||||
first = 1
|
||||
while (first <= line_count && lines[first] ~ /^[ ]*$/) {
|
||||
first++
|
||||
}
|
||||
|
||||
last = line_count
|
||||
while (last >= first && lines[last] ~ /^[ ]*$/) {
|
||||
last--
|
||||
}
|
||||
|
||||
for (i = first; i <= last; i++) {
|
||||
print lines[i]
|
||||
}
|
||||
}
|
||||
' >"$tmp_output"; then
|
||||
echo "Unable to convert logo image: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -s $tmp_output ]]; then
|
||||
echo "No logo pixels found in: $image_path" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $output_path == "-" ]]; then
|
||||
cat "$tmp_output"
|
||||
else
|
||||
mkdir -p "$(dirname "$output_path")"
|
||||
cp "$tmp_output" "$output_path"
|
||||
echo "Wrote screensaver logo text to $output_path"
|
||||
fi
|
||||
Reference in New Issue
Block a user