/ de-omarchy / bin / omarchy-screensaver
swadhinbiswas fix(plugin-manager): close on Esc/outside-click and harden marketplace RCE - shell/plugins/plugin-manager/Panel.qml:6,139,149,155,358,368,384,404,409,426,439,457,508 — PanelWindow had WlrKeyboardFocus: Exclusive always, no PanelKeyCatcher/Keys.onEscape and no outside-click MouseArea → once opened via keymap.lua:159 SUPER+SHIFT+I (shell/shell.qml:465 summon) only bar-icon BarWidget.qml:67 could close; add Quickshell.Wayland import, keyboardFocus: opened?Exclusive:None, onVisibleChanged/onOpenedChanged Qt.callLater(keyCatcher.forceActiveFocus()), scrim Qt.rgba(0,0,0,0.45), dismiss MouseArea (modal-aware) + Item#keyCatcher { focus:true; Keys.priority:BeforeItem; Esc->closeModal/close } + card swallow MouseArea, mirrors clipboard/Clipboard.qml:329; fix loadInstalled/loadMarketplace and all actionProc.command single-quote injections (enable/disable, bar remove/add, shortcut set/remove, install, install url, remove) → Util.shellQuote - plugin-library/shell.qml:104,115,121,429,439,455,475,480,495,508,526 — same injection via "'"+p.id+"'" without quoting (marketplace id/url/keys controlled by remote catalog) → add local shellQuote(v) (Util.shellQuote not importable in standalone ShellRoot) and use for all actionProc.command + loadInstalled/loadMarketplace (home/om paths); add Window#win Item { focus:true; Keys.onPressed: Esc { closeModal · 8/27/2026
4aa0eee
92 lines · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/bin/bash

# omarchy:summary=Run the Omarchy screensaver using random effects from TTE.

screensaver_in_focus() {
  hyprctl activewindow -j | jq -e '.class == "org.omarchy.screensaver"' >/dev/null 2>&1
}

exit_screensaver() {
  hyprctl eval 'hl.config({ cursor = { invisible = false } })' &>/dev/null || hyprctl keyword cursor:invisible false &>/dev/null || true
  # Upstream's own pacman repo ships the Rust port as `ttfx`; everywhere else
  # the engine comes from python-terminaltexteffects as `tte`.
  pkill -x ttfx 2>/dev/null
  pkill -x tte 2>/dev/null
  pkill -f '[o]rg.omarchy.screensaver' 2>/dev/null
  exit 0
}

# Exit the screensaver on signals and input from keyboard and mouse
trap exit_screensaver SIGINT SIGTERM SIGHUP SIGQUIT

printf '\033]11;rgb:00/00/00\007'  # Set background color to black

hyprctl eval 'hl.config({ cursor = { invisible = true } })' &>/dev/null || hyprctl keyword cursor:invisible true &>/dev/null

tty=$(tty 2>/dev/null)

# Terminals allocate the pty at the default 80x24 and only resize it once the
# compositor has told the window how big it is. The engine measures the
# terminal once, at startup, so starting it before the resize lands sizes an
# 80x24 canvas and paints it into the corner of a fullscreen window.
wait_for_terminal_resize() {
  local deadline=$((SECONDS + 2))
  while ((SECONDS < deadline)) && [[ $(stty size 2>/dev/null) == "24 80" ]]; do
    sleep 0.02
  done
}

wait_for_terminal_resize

# Engine resolution — the ONE structural delta from upstream. Upstream's repo
# ships `ttfx` (a dependency-free Rust port, swapped in for `tte` in 4e31b61a);
# outside that repo the same engine installs from python-terminaltexteffects as
# `tte`, with identical option names, defaults, and exit codes — so the
# invocation below is unchanged apart from the command name.
if command -v ttfx >/dev/null 2>&1; then
  SCREENSAVER_ENGINE=ttfx
elif command -v tte >/dev/null 2>&1; then
  SCREENSAVER_ENGINE=tte
fi

# Branding art: the user's copy first, the shipped logo as fallback. Without
# an input file the engine would error on every loop iteration, so bail out
# instead (upstream's ISO provisions the branding file; a layered install may
# not have it).
SCREENSAVER_INPUT="$HOME/.config/omarchy/branding/screensaver.txt"
[[ -f $SCREENSAVER_INPUT ]] || SCREENSAVER_INPUT="${OMARCHY_PATH:-/usr/share/de-omarchy}/logo.txt"

# No engine installed: render the branding art statically instead of spinning
# on command-not-found forever. Upstream never hits this branch.
run_static_screensaver() {
  clear
  cat "$SCREENSAVER_INPUT"
  printf '\n\n  (animated effects need ttfx or tte — showing static art)\n'
  while screensaver_in_focus; do
    if read -n1 -t 1; then
      exit_screensaver
    fi
  done
  exit_screensaver
}

if [[ ! -f $SCREENSAVER_INPUT ]]; then
  exit_screensaver
fi

if [[ -z ${SCREENSAVER_ENGINE:-} ]]; then
  run_static_screensaver
fi

while true; do
  "$SCREENSAVER_ENGINE" -i "$SCREENSAVER_INPUT" \
    --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 "$SCREENSAVER_ENGINE" >/dev/null; do
    if read -n1 -t 1 || ! screensaver_in_focus; then
      exit_screensaver
    fi
  done
done