Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/omarchy
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ GROUP_DESCRIPTIONS[bluetooth]="Bluetooth device controls"
GROUP_DESCRIPTIONS[branch]="Omarchy git branch management"
GROUP_DESCRIPTIONS[branding]="About and screensaver branding"
GROUP_DESCRIPTIONS[brightness]="Display and keyboard brightness"
GROUP_DESCRIPTIONS[cache]="Menu thumbnail cache warming"
GROUP_DESCRIPTIONS[capture]="Screenshots and screen recording"
GROUP_DESCRIPTIONS[channel]="Omarchy release channel management"
GROUP_DESCRIPTIONS[clipboard]="Clipboard helpers"
Expand Down
23 changes: 23 additions & 0 deletions bin/omarchy-cache-warm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

# omarchy:summary=Pre-build the theme, background, and unlock menu thumbnail caches

# The theme, background, and unlock selectors all render 1536x864 thumbnails on
# first open, which is the one slow open on a fresh machine. Building them up
# front makes every first open instant. Everything here is idempotent and skips
# work that is already cached, so it is cheap to run again.
#
# Warming is best effort: it reports failures on stderr but always succeeds, so
# a cache that can't be built never aborts user setup or a migration.

warm() {
if ! nice -n 19 ionice -c 3 "$@" >/dev/null; then
echo "omarchy-cache-warm: $1 failed" >&2
fi
}

warm omarchy-theme-switcher --cache-only
warm omarchy-theme-bg-cache
warm omarchy-plymouth-switcher --cache-only

exit 0
33 changes: 29 additions & 4 deletions bin/omarchy-plymouth-current
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,43 @@
# omarchy:summary=Show which theme is styling the Plymouth boot screen
# omarchy:examples=omarchy plymouth current

# omarchy-plymouth-set installs the theme's unlock.png as a byte-for-byte
# copy of logo.png, so matching it back identifies the current theme.
# omarchy-plymouth-set installs the theme's unlock logo as a byte-for-byte copy
# of logo.png, so matching it back identifies the current theme. Generated logos
# are deterministic, so they compare equal to what was installed from them.
installed_logo=/usr/share/plymouth/themes/omarchy/logo.png

[[ -f $installed_logo ]] || exit

if cmp -s "$OMARCHY_PATH/default/plymouth/logo.png" "$installed_logo"; then
echo default
exit
fi

omarchy-plymouth-list | while read -r name; do
if cmp -s "$(omarchy-theme-dir "$name")/unlock.png" "$installed_logo"; then
names=()
logos=()

while IFS= read -r name; do
logo=$(omarchy-plymouth-logo "$name") || continue

if cmp -s "$logo" "$installed_logo"; then
echo "$name"
exit
fi

names+=("$name")
logos+=("$logo")
done < <(omarchy-plymouth-list)

# A logo installed before its theme's art was generated rather than committed
# can carry different PNG metadata while drawing the same pixels, so fall back
# to comparing pixel content.
installed_signature=$(magick "$installed_logo" -quiet -format '%#' info: 2>/dev/null)

[[ -n $installed_signature ]] || exit

for index in "${!names[@]}"; do
if [[ $(magick "${logos[$index]}" -quiet -format '%#' info: 2>/dev/null) == "$installed_signature" ]]; then
echo "${names[$index]}"
exit
fi
done
6 changes: 4 additions & 2 deletions bin/omarchy-plymouth-list
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
# omarchy:summary=List themes that can style the Plymouth boot screen
# omarchy:examples=omarchy plymouth list

# Any theme with a palette can style the boot screen: the unlock logo and its
# preview are generated from colors.toml when the theme doesn't ship its own.
{
find ~/.config/omarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%f\n' 2>/dev/null
find "$OMARCHY_PATH/themes/" -mindepth 1 -maxdepth 1 -type d -printf '%f\n'
} | sort -u | while read -r name; do
if [[ -f $(omarchy-theme-dir "$name")/preview-unlock.png ]]; then
} | sort -u | while IFS= read -r name; do
if [[ -f $(omarchy-theme-dir "$name")/colors.toml ]]; then
echo "$name"
fi
done
61 changes: 61 additions & 0 deletions bin/omarchy-plymouth-logo
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash

# omarchy:summary=Print the unlock logo for a theme, generating one when the theme ships none
# omarchy:args=<theme-name>
# omarchy:hidden=true

# Most themes want nothing more than the Omarchy logo in their accent color, so
# that baseline is generated on demand and cached instead of being committed to
# every theme. A theme only needs to ship unlock.png when it wants different art.

if (( $# != 1 )); then
echo "Usage: omarchy-plymouth-logo <theme-name>" >&2
exit 1
fi

theme="$1"
theme_dir=$(omarchy-theme-dir "$theme")

if [[ -f $theme_dir/unlock.png ]]; then
printf '%s\n' "$theme_dir/unlock.png"
exit 0
fi

colors_file="$theme_dir/colors.toml"

if [[ ! -f $colors_file ]]; then
echo "No colors.toml for theme: $theme" >&2
exit 1
fi

source_logo="$OMARCHY_PATH/default/plymouth/logo.png"
cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/omarchy/plymouth/$theme"

# The cache file is named after its inputs, so publishing it is a single atomic
# rename. Concurrent generators can never pair one run's image with another
# run's signature, and a user theme shadowing a built-in one of the same name
# gets its own entry because the resolved theme directory is part of the name.
signature="v2 $theme_dir $(stat -Lc '%s:%Y' "$colors_file") $(stat -Lc '%s:%Y' "$source_logo")"
logo="$cache_dir/unlock-$(printf '%s' "$signature" | md5sum | cut -d ' ' -f 1).png"

if [[ -f $logo ]]; then
printf '%s\n' "$logo"
exit 0
fi

accent=$(omarchy-theme-color --file "$colors_file" accent foreground)

mkdir -p "$cache_dir"

# -strip and png:exclude-chunk=time keep the output byte-identical across
# regenerations so omarchy-plymouth-current can cmp against the installed logo.
if ! magick "$source_logo" \
-channel RGB +level-colors "$accent","$accent" \
-strip -define png:exclude-chunk=time \
"$logo.$$.png" || ! mv -f "$logo.$$.png" "$logo"; then
rm -f "$logo.$$.png"
echo "Failed to generate unlock logo for theme: $theme" >&2
exit 1
fi

printf '%s\n' "$logo"
27 changes: 22 additions & 5 deletions bin/omarchy-plymouth-preview
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
#!/bin/bash

# omarchy:summary=Preview a Plymouth boot screen with custom colors and logo
# omarchy:args=<background-hex> <text-hex> <path-to-logo.png> <output-path>
# omarchy:args=[--no-open] <background-hex> <text-hex> <path-to-logo.png> <output-path>
# omarchy:examples=omarchy plymouth preview '#1d2021' '#ebdbb2' ~/.local/state/omarchy/current/theme/plymouth/logo.png /tmp/plymouth-preview.png

# Render a Plymouth login-screen preview PNG by compositing the staged omarchy
# theme assets (recolored with the given text color) onto the background.
# Pass --no-open to only write the file, which is what the per-theme previews
# in omarchy-plymouth-preview-by-theme need.

open_preview=true

if [[ $1 == "--no-open" ]]; then
open_preview=false
shift
fi

if (( $# != 4 )); then
echo "Usage: omarchy-plymouth-preview <background-hex> <text-hex> <path-to-logo.png> <output-path>" >&2
echo "Usage: omarchy-plymouth-preview [--no-open] <background-hex> <text-hex> <path-to-logo.png> <output-path>" >&2
exit 1
fi

Expand Down Expand Up @@ -66,11 +75,19 @@ for i in 0 1 2 3; do
bullet_args+=( '(' "$staging_dir/bullet.png" -resize 7x7 ')' -geometry +${bx}+${bullet_y} -composite )
done

magick -size ${canvas_w}x${canvas_h} "xc:#$bg_hex" \
# -strip and png:exclude-chunk=time keep repeated renders byte-identical so the
# generated previews can be cached and compared without spurious churn.
if ! magick -size ${canvas_w}x${canvas_h} "xc:#$bg_hex" \
"$staging_dir/logo.png" -geometry +${logo_x}+${logo_y} -composite \
"$staging_dir/entry.png" -geometry +${entry_x}+${entry_y} -composite \
\( "$staging_dir/lock.png" -resize ${lock_w}x${lock_h} \) -geometry +${lock_x}+${lock_y} -composite \
"${bullet_args[@]}" \
"$output_path"
-strip -define png:exclude-chunk=time \
"$output_path"; then
echo "Failed to render Plymouth preview: $output_path" >&2
exit 1
fi

imv -f "$output_path"
if [[ $open_preview == true ]]; then
imv -f "$output_path"
fi
62 changes: 62 additions & 0 deletions bin/omarchy-plymouth-preview-by-theme
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash

# omarchy:summary=Print the unlock screen preview for a theme, rendering one when the theme ships none
# omarchy:args=<theme-name>
# omarchy:hidden=true

# A theme only needs to commit preview-unlock.png when it wants art that differs
# from what the boot screen actually draws. Otherwise the preview is rendered
# from the theme's unlock logo and colors, then cached.

if (( $# != 1 )); then
echo "Usage: omarchy-plymouth-preview-by-theme <theme-name>" >&2
exit 1
fi

theme="$1"
theme_dir=$(omarchy-theme-dir "$theme")

if [[ -f $theme_dir/preview-unlock.png ]]; then
printf '%s\n' "$theme_dir/preview-unlock.png"
exit 0
fi

colors_file="$theme_dir/colors.toml"

if [[ ! -f $colors_file ]]; then
echo "No colors.toml for theme: $theme" >&2
exit 1
fi

logo=$(omarchy-plymouth-logo "$theme") || exit 1

cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/omarchy/plymouth/$theme"

# Named after its inputs for the same reason as the unlock logo: publishing is
# one atomic rename, so no reader can see a stale image treated as current.
signature="v2 $theme_dir $(stat -Lc '%s:%Y' "$colors_file") $(stat -Lc '%s:%Y' "$logo")"

for asset in bullet.png entry.png lock.png; do
signature+=" $(stat -Lc '%s:%Y' "$OMARCHY_PATH/default/plymouth/$asset")"
done

preview="$cache_dir/preview-$(printf '%s' "$signature" | md5sum | cut -d ' ' -f 1).png"

if [[ -f $preview ]]; then
printf '%s\n' "$preview"
exit 0
fi

background=$(omarchy-theme-color --file "$colors_file" background)
foreground=$(omarchy-theme-color --file "$colors_file" foreground)

mkdir -p "$cache_dir"

if ! omarchy-plymouth-preview --no-open "$background" "$foreground" "$logo" "$preview.$$.png" ||
! mv -f "$preview.$$.png" "$preview"; then
rm -f "$preview.$$.png"
echo "Failed to render unlock preview for theme: $theme" >&2
exit 1
fi

printf '%s\n' "$preview"
51 changes: 13 additions & 38 deletions bin/omarchy-plymouth-set-by-theme
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# omarchy:args=<theme-name>
# omarchy:requires-sudo=true

# Resolve a theme by name and apply its unlock.png + colors.toml as the
# Resolve a theme by name and apply its unlock logo + colors.toml as the
# Plymouth boot screen via omarchy-plymouth-set.

if (( $# != 1 )); then
Expand All @@ -13,41 +13,16 @@ if (( $# != 1 )); then
fi

theme=$1
colors_file="$(omarchy-theme-dir "$theme")/colors.toml"

theme_dir=$(omarchy-theme-dir "$theme")

theme_color() {
local key="$1"
local fallback="$2"

awk -F= -v key="$key" -v fallback="$fallback" '
function clean(raw) {
gsub(/^[[:space:]]+|[[:space:]]+$/, "", raw)
if (raw ~ /^"/) {
sub(/^"/, "", raw)
sub(/".*$/, "", raw)
}
return raw
}

{
field = $1
gsub(/^[[:space:]]+|[[:space:]]+$/, "", field)
if (field == key) {
print clean($2)
found = 1
exit
}
if (field == fallback) fallback_value = clean($2)
}

END {
if (!found && fallback_value != "") print fallback_value
}
' "$theme_dir/colors.toml"
}

bg=$(theme_color background)
text=$(theme_color foreground)

exec omarchy-plymouth-set "$bg" "$text" "$theme_dir/unlock.png"
if [[ ! -f $colors_file ]]; then
echo "No colors.toml for theme: $theme" >&2
exit 1
fi

logo=$(omarchy-plymouth-logo "$theme") || exit 1

bg=$(omarchy-theme-color --file "$colors_file" background)
text=$(omarchy-theme-color --file "$colors_file" foreground)

exec omarchy-plymouth-set "$bg" "$text" "$logo"
19 changes: 17 additions & 2 deletions bin/omarchy-plymouth-switcher
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
#!/bin/bash

# omarchy:summary=Open the Plymouth unlock screen switcher
# omarchy:args=[--cache-only]

# --cache-only renders every theme's unlock preview and warms the selector
# thumbnails without opening the menu.
cache_only=false

if [[ $1 == "--cache-only" ]]; then
cache_only=true
shift
fi

preview_dir="${XDG_CACHE_HOME:-$HOME/.cache}/omarchy/unlock-selector/previews"

Expand All @@ -9,10 +19,15 @@ mkdir -p "$preview_dir"

ln -s "$OMARCHY_PATH/default/plymouth/preview-unlock.png" "$preview_dir/default.png"

omarchy-plymouth-list | while read -r name; do
ln -s "$(omarchy-theme-dir "$name")/preview-unlock.png" "$preview_dir/$name.png" 2>/dev/null
omarchy-plymouth-list | while IFS= read -r name; do
preview=$(omarchy-plymouth-preview-by-theme "$name") || continue
ln -s "$preview" "$preview_dir/$name.png" 2>/dev/null
done

if [[ $cache_only == true ]]; then
exec omarchy-menu-images --cache-only "$preview_dir"
fi

current=$(omarchy-plymouth-current)
selected=""
[[ -n $current && -e $preview_dir/$current.png ]] && selected="$preview_dir/$current.png"
Expand Down
Loading