From 4e31b61af09c5fb5a981b189f95895e342b00ee4 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 10 Aug 2026 11:59:39 +0200 Subject: [PATCH] Swap terminaltexteffects for ttfx (#6670) * Swap terminaltexteffects for ttfx ttfx is a Rust port of terminaltexteffects that renders byte-identical frames as a single dependency-free binary. Same option names, defaults, and exit codes, so every invocation here is unchanged apart from the command name. The screensaver runs at --frame-rate 120 with --random-effect. On a fullscreen canvas Python cannot hold that for the heavier effects (beams: 14.1 ms/frame against an 8.3 ms budget, so ~71fps); ttfx renders the same effect at 564fps. Startup drops from ~107 ms to ~1 ms, and the base image no longer needs Python for the screensaver. Co-Authored-By: Claude Fable 5 * Need a migration --------- Co-authored-by: Claude Fable 5 --- bin/omarchy-debug-idle | 2 +- bin/omarchy-launch-screensaver | 2 +- bin/omarchy-provision-owner | 18 +++++++++--------- bin/omarchy-screensaver | 6 +++--- install/omarchy-base.packages | 2 +- migrations/1786355450.sh | 4 ++++ 6 files changed, 19 insertions(+), 15 deletions(-) create mode 100644 migrations/1786355450.sh diff --git a/bin/omarchy-debug-idle b/bin/omarchy-debug-idle index 73db24bd..62a38cf1 100755 --- a/bin/omarchy-debug-idle +++ b/bin/omarchy-debug-idle @@ -32,7 +32,7 @@ journalctl -t omarchy-shell -n "$lines" --no-pager --quiet 2>/dev/null || true section "Relevant processes" ps -eo pid=,args= \ - | grep -E 'quickshell -n -p|omarchy-system-sleep-monitor|systemd-inhibit.*Lock screen before suspend|org\.omarchy\.screensaver|omarchy-screensaver|(^|/| )tte( |$)' \ + | grep -E 'quickshell -n -p|omarchy-system-sleep-monitor|systemd-inhibit.*Lock screen before suspend|org\.omarchy\.screensaver|omarchy-screensaver|(^|/| )ttfx( |$)' \ | grep -v grep || true section "Sleep lock service" diff --git a/bin/omarchy-launch-screensaver b/bin/omarchy-launch-screensaver index 77122efd..afee404b 100755 --- a/bin/omarchy-launch-screensaver +++ b/bin/omarchy-launch-screensaver @@ -2,7 +2,7 @@ # omarchy:summary=Launch the Omarchy screensaver in the default terminal on the system with the correct font configuration. -if omarchy-cmd-missing tte; then +if omarchy-cmd-missing ttfx; then exit 1 fi diff --git a/bin/omarchy-provision-owner b/bin/omarchy-provision-owner index 53f6234d..7b771038 100755 --- a/bin/omarchy-provision-owner +++ b/bin/omarchy-provision-owner @@ -412,7 +412,7 @@ greeter_screen() { # nested function so the wait loop below can repaint it verbatim if the VT # resizes out from under us: a late resize (virtio-gpu KMS handoff, or the SDL # window's size arriving) scrolls the old frame into the top-left and resets - # the DEC saved cursor tte paints from — exactly the tiled/garbled logo we saw + # the DEC saved cursor ttfx paints from — exactly the tiled/garbled logo we saw # on a fresh first boot. Redrawing on every resize beats any fixed-length # startup wait, which can only ever guess when the console has stopped moving. _greeter_draw() { @@ -464,7 +464,7 @@ greeter_screen() { # ColorShift the logo: a green base (indexed color 2) with a cyan accent (6) # drifting through, settling on green. Indexed ANSI colors, not hex — the - # framebuffer console can't render tte's truecolor faithfully (it crushes the + # framebuffer console can't render ttfx's truecolor faithfully (it crushes the # palette to a muddy lavender), but the 16 indexed colors map to the Tokyo # Night palette and render true. One long-running invocation (many cycles) so # it never restarts — a restart is what flashed. The effect reads from @@ -472,13 +472,13 @@ greeter_screen() { # --reuse-canvas paints upward from the saved cursor, anchored one row below # the logo to repaint exactly the rows drawn above. --canvas-width is cols-1 # to stay off the autowrap column. - if command -v tte >/dev/null 2>&1; then + if command -v ttfx >/dev/null 2>&1; then printf '%s%d;1H\0337' "$CSI" "$((logo_row + LOGO_HEIGHT))" - # Run tte directly (not inside a `while` subshell) so $anim is tte's own - # PID: killing a wrapping subshell would orphan tte, which then keeps + # Run ttfx directly (not inside a `while` subshell) so $anim is ttfx's own + # PID: killing a wrapping subshell would orphan ttfx, which then keeps # painting the logo over the keyboard step. --cycles is high enough that it # never ends on its own before Return. - tte -i "$LOGO_PATH" \ + ttfx -i "$LOGO_PATH" \ --canvas-width "$((cols - 1))" \ --anchor-text c \ --frame-rate 60 \ @@ -495,8 +495,8 @@ greeter_screen() { _greeter_kill_anim() { [[ -n ${anim:-} ]] || return 0 - # Guard both: `kill` returns non-zero if tte already exited (crash, or a - # resize race), and `wait` reports tte's kill signal (143) — either would + # Guard both: `kill` returns non-zero if ttfx already exited (crash, or a + # resize race), and `wait` reports ttfx's kill signal (143) — either would # abort provisioning under `set -e` and drop straight to the login screen. kill "$anim" 2>/dev/null || true wait "$anim" 2>/dev/null || true @@ -537,7 +537,7 @@ greeter_screen() { trap - WINCH _greeter_kill_anim - # tte leaves the tty in raw/no-echo mode when killed; restore it or the gum + # ttfx leaves the tty in raw/no-echo mode when killed; restore it or the gum # prompts in the keyboard step that follows silently die. Then clear the # leftover animation frame. stty sane /dev/null || true diff --git a/bin/omarchy-screensaver b/bin/omarchy-screensaver index 040d772a..c319234a 100755 --- a/bin/omarchy-screensaver +++ b/bin/omarchy-screensaver @@ -8,7 +8,7 @@ screensaver_in_focus() { exit_screensaver() { hyprctl eval 'hl.config({ cursor = { invisible = false } })' &>/dev/null || hyprctl keyword cursor:invisible false &>/dev/null || true - pkill -x tte 2>/dev/null + pkill -x ttfx 2>/dev/null pkill -f '[o]rg.omarchy.screensaver' 2>/dev/null exit 0 } @@ -23,11 +23,11 @@ hyprctl eval 'hl.config({ cursor = { invisible = true } })' &>/dev/null || hyprc tty=$(tty 2>/dev/null) while true; do - tte -i ~/.config/omarchy/branding/screensaver.txt \ + ttfx -i ~/.config/omarchy/branding/screensaver.txt \ --frame-rate 120 --canvas-width 0 --canvas-height 0 --reuse-canvas --anchor-canvas c --anchor-text c\ --random-effect --no-eol --no-restore-cursor & - while pgrep -t "${tty#/dev/}" -x tte >/dev/null; do + while pgrep -t "${tty#/dev/}" -x ttfx >/dev/null; do if read -n1 -t 1 || ! screensaver_in_focus; then exit_screensaver fi diff --git a/install/omarchy-base.packages b/install/omarchy-base.packages index 2244462a..44044e7a 100644 --- a/install/omarchy-base.packages +++ b/install/omarchy-base.packages @@ -104,7 +104,7 @@ postgresql-libs power-profiles-daemon python-gobject python-poetry-core -python-terminaltexteffects +ttfx qemu-user-static-binfmt qrencode quickshell-git diff --git a/migrations/1786355450.sh b/migrations/1786355450.sh new file mode 100644 index 00000000..94f3154d --- /dev/null +++ b/migrations/1786355450.sh @@ -0,0 +1,4 @@ +echo "Replace terminaltexteffects with ttfx" + +omarchy-pkg-add ttfx +omarchy-pkg-drop python-terminaltexteffects