Compare commits
4
Commits
deeacbe580
...
d316308bf5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d316308bf5 | ||
|
|
64afc07250 | ||
|
|
e74c9c5bc1 | ||
|
|
a9b9ba6ba4 |
@@ -2,7 +2,8 @@
|
||||
|
||||
# blob:summary=Launch the Blob screensaver in the default terminal on the system with the correct font configuration.
|
||||
|
||||
if blob-cmd-missing ttfx; then
|
||||
if ! blob-screensaver-effect >/dev/null; then
|
||||
blob-notify-send -g ✋ "Screensaver needs ttfx or tte" "Install python-terminaltexteffects."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
+28
-5
@@ -2,13 +2,37 @@
|
||||
|
||||
# blob:summary=Run the Blob screensaver using random effects from TTE.
|
||||
|
||||
effect_command=$(blob-screensaver-effect) || exit 1
|
||||
|
||||
effect_args() {
|
||||
local input="$HOME/.config/blob/branding/screensaver.txt"
|
||||
|
||||
if [[ $effect_command == "ttfx" ]]; then
|
||||
printf '%s\n' -i "$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
|
||||
return 0
|
||||
fi
|
||||
|
||||
local effects=(
|
||||
beams binarypath blackhole bouncyballs bubbles burn colorshift crumble
|
||||
decrypt errorcorrect expand fireworks middleout orbittingvolley overflow
|
||||
pour print rain randomsequence rings scattered slice slide spotlights
|
||||
spray swarm sweep synthgrid unstable vhstape waves wipe
|
||||
)
|
||||
|
||||
printf '%s\n' -i "$input" --frame-rate 120 --canvas-width 0 --canvas-height 0 \
|
||||
--anchor-canvas c --anchor-text c --no-color \
|
||||
"${effects[RANDOM % ${#effects[@]}]}"
|
||||
}
|
||||
|
||||
screensaver_in_focus() {
|
||||
hyprctl activewindow -j | jq -e '.class == "org.blob.screensaver"' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
exit_screensaver() {
|
||||
hyprctl eval 'hl.config({ cursor = { invisible = false } })' &>/dev/null || hyprctl keyword cursor:invisible false &>/dev/null || true
|
||||
pkill -x ttfx 2>/dev/null
|
||||
pkill -x "$effect_command" 2>/dev/null
|
||||
pkill -f '[o]rg.blob.screensaver' 2>/dev/null
|
||||
exit 0
|
||||
}
|
||||
@@ -36,11 +60,10 @@ wait_for_terminal_resize() {
|
||||
wait_for_terminal_resize
|
||||
|
||||
while true; do
|
||||
ttfx -i ~/.config/blob/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 &
|
||||
mapfile -t effect_arguments < <(effect_args)
|
||||
"$effect_command" "${effect_arguments[@]}" &
|
||||
|
||||
while pgrep -t "${tty#/dev/}" -x ttfx >/dev/null; do
|
||||
while pgrep -t "${tty#/dev/}" -x "$effect_command" >/dev/null; do
|
||||
if read -n1 -t 1 || ! screensaver_in_focus; then
|
||||
exit_screensaver
|
||||
fi
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# blob:summary=Print the terminal text effects command the screensaver can use
|
||||
# blob:hidden=true
|
||||
|
||||
for candidate in ttfx tte; do
|
||||
if command -v "$candidate" &>/dev/null; then
|
||||
printf '%s\n' "$candidate"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
exit 1
|
||||
@@ -20,7 +20,8 @@ if pgrep -x "1password" >/dev/null && blob-cmd-present 1password; then
|
||||
fi
|
||||
|
||||
# Avoid running screensaver when locked
|
||||
pkill -x ttfx 2>/dev/null || true
|
||||
# ttfx handles SIGTERM asynchronously, so keep its terminal alive until it exits.
|
||||
timeout 1s pidwait -x ttfx 2>/dev/null || true
|
||||
effect_command=$(blob-screensaver-effect 2>/dev/null) && {
|
||||
pkill -x "$effect_command" 2>/dev/null || true
|
||||
timeout 1s pidwait -x "$effect_command" 2>/dev/null || true
|
||||
}
|
||||
pkill -f '[o]rg.blob.screensaver' 2>/dev/null || true
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<match target="pattern">
|
||||
<test name="family" qual="any">
|
||||
<string>monospace</string>
|
||||
</test>
|
||||
<edit name="family" mode="prepend_first" binding="strong">
|
||||
<string>JetBrainsMono Nerd Font</string>
|
||||
</edit>
|
||||
</match>
|
||||
</fontconfig>
|
||||
@@ -0,0 +1,2 @@
|
||||
#%PAM-1.0
|
||||
auth include system-auth
|
||||
@@ -14,7 +14,7 @@ theme[hi_fg]="{{ accent }}"
|
||||
theme[selected_bg]="{{ selection }}"
|
||||
|
||||
# Foreground color of selected item in processes box
|
||||
theme[selected_fg]="{{ accent }}"
|
||||
theme[selected_fg]="{{ selection_foreground }}"
|
||||
|
||||
# Color of inactive/disabled text
|
||||
theme[inactive_fg]="{{ muted }}"
|
||||
@@ -23,7 +23,7 @@ theme[inactive_fg]="{{ muted }}"
|
||||
theme[graph_text]="{{ light_foreground }}"
|
||||
|
||||
# Background color of the percentage meters
|
||||
theme[meter_bg]="{{ selection }}"
|
||||
theme[meter_bg]="{{ lighter_background }}"
|
||||
|
||||
# Misc colors for processes box including mini cpu graphs, details memory graph and details status text
|
||||
theme[proc_misc]="{{ light_foreground }}"
|
||||
|
||||
@@ -1,31 +1,41 @@
|
||||
add_newline = true
|
||||
command_timeout = 200
|
||||
format = "[$directory$git_branch$git_status]($style)$character"
|
||||
palette = "blob"
|
||||
|
||||
[palettes.blob]
|
||||
accent = "{{ accent }}"
|
||||
foreground = "{{ foreground }}"
|
||||
muted = "{{ muted }}"
|
||||
success = "{{ green }}"
|
||||
warning = "{{ yellow }}"
|
||||
error = "{{ red }}"
|
||||
|
||||
[character]
|
||||
error_symbol = "[✗](bold cyan)"
|
||||
success_symbol = "[❯](bold cyan)"
|
||||
error_symbol = "[✗](bold error)"
|
||||
success_symbol = "[❯](bold accent)"
|
||||
|
||||
[directory]
|
||||
style = "foreground"
|
||||
truncation_length = 2
|
||||
truncation_symbol = "…/"
|
||||
repo_root_style = "bold cyan"
|
||||
repo_root_style = "bold accent"
|
||||
repo_root_format = "[$repo_root]($repo_root_style)[$path]($style)[$read_only]($read_only_style) "
|
||||
|
||||
[git_branch]
|
||||
format = "[$branch]($style) "
|
||||
style = "italic cyan"
|
||||
style = "italic accent"
|
||||
|
||||
[git_status]
|
||||
format = '[$all_status]($style)'
|
||||
style = "cyan"
|
||||
style = "warning"
|
||||
ahead = "⇡${count} "
|
||||
diverged = "⇕⇡${ahead_count}⇣${behind_count} "
|
||||
behind = "⇣${count} "
|
||||
conflicted = " "
|
||||
up_to_date = " "
|
||||
conflicted = " "
|
||||
up_to_date = " "
|
||||
untracked = "? "
|
||||
modified = " "
|
||||
modified = " "
|
||||
stashed = ""
|
||||
staged = ""
|
||||
renamed = ""
|
||||
+24
-1
@@ -35,7 +35,17 @@ with `--check`.
|
||||
resolves cannot cost you the other hundred and the config, service and login
|
||||
steps below. See [packages.md](packages.md).
|
||||
4. **Config** is copied into `~/.config`: `hypr/`, the themed app configs,
|
||||
`blob/shell.json`, the uwsm environment, and the icon font.
|
||||
`blob/shell.json`, the uwsm environment, `fontconfig/fonts.conf`, and the
|
||||
icon font, and the font cache is refreshed. The shell draws every icon as a
|
||||
Nerd Font glyph in the `monospace` family, and on a fresh Arch install
|
||||
fontconfig resolves that to a font with no such glyphs, so the bar and its
|
||||
panels come up full of blanks. `fonts.conf` binds `monospace` to
|
||||
`JetBrainsMono Nerd Font`; `blob font set` rewrites the same file, and the
|
||||
installer then reports it as a local change and keeps your choice.
|
||||
`~/.bashrc` gets one line sourcing `session/bashrc`, which is what starts
|
||||
the starship prompt and puts `blob` on `PATH` in an interactive shell. The
|
||||
line is added once, a `.bak` is kept, and a `~/.bashrc` that already has it
|
||||
is left alone.
|
||||
`session/profile.sh` also goes to `/etc/profile.d/blob.sh`, which sources
|
||||
`session/env-bootstrap` and is what puts `blob` on `PATH` in a login shell.
|
||||
Without it `BLOB_PATH` and `$BLOB_PATH/bin` are only set by
|
||||
@@ -87,6 +97,7 @@ with `--check`.
|
||||
| `/etc/sddm.conf.d/zz-blob.conf` | Wayland greeter, run on Hyprland, stock theme, remember the last session |
|
||||
| `/etc/sddm/hyprland-greeter.lua` | the greeter's own tiny Hyprland config |
|
||||
| `/usr/local/bin/blob-hw-gpu-accelerated` | the renderer check that config runs, where SDDM's user can read it |
|
||||
| `/etc/pam.d/blob-lock-password` | the PAM stack the lock screen authenticates against |
|
||||
|
||||
The greeter config matters more than it looks: SDDM's stock Wayland greeter
|
||||
runs on `weston`, which Blob does not install, so a default SDDM would fail
|
||||
@@ -135,6 +146,18 @@ with `--check`.
|
||||
| `--autologin` | skip the SDDM prompt for this user |
|
||||
| `--no-launch` | leave the login screen for the next reboot |
|
||||
|
||||
## The lock screen
|
||||
|
||||
The lock plugin watches `/etc/pam.d/blob-lock-password` and refuses to lock at
|
||||
all when it is not there - `blob system lock` returns `missing-pam` and nothing
|
||||
appears, which reads as a keybinding that does nothing. The installer writes it;
|
||||
it is one line including `system-auth`, the same stack every other Wayland
|
||||
locker on Arch authenticates against.
|
||||
|
||||
Fingerprint unlock is separate and opt-in: `blob setup-security-fingerprint`
|
||||
writes `/etc/pam.d/blob-lock-fingerprint`, and the lock only offers fingerprint
|
||||
when that file and a reader are both present.
|
||||
|
||||
## Choosing a renderer
|
||||
|
||||
Hyprland renders through Mesa, and on an adapter Mesa has no driver for it exits
|
||||
|
||||
+2
-1
@@ -70,7 +70,7 @@ Two are worth knowing about:
|
||||
|
||||
```
|
||||
packages/blob.packages 121 packages from core, extra, multilib
|
||||
packages/blob-aur.packages 10 packages with no official equivalent
|
||||
packages/blob-aur.packages 11 packages with no official equivalent
|
||||
```
|
||||
|
||||
Only missing packages are touched, through `pacman -S --needed` and
|
||||
@@ -127,6 +127,7 @@ Omarchy's own package list, because they were installed by hand on this machine:
|
||||
| Package | Needed by |
|
||||
| --- | --- |
|
||||
| `python-pywal16` | `blob-wallpaper-set`, palette extraction |
|
||||
| `python-terminaltexteffects` | `blob-screensaver`, the effects it draws |
|
||||
| `awww` | the wallpaper daemon `blob-wallpaper-set` and `blob-theme-menu` drive |
|
||||
| `playerctl` | the quick settings media row |
|
||||
|
||||
|
||||
+19
-4
@@ -30,12 +30,13 @@ the shell and the CLI never disagree about what a slot means.
|
||||
Each rendered file is picked up differently: `foot.ini` and `kitty.conf` by an
|
||||
`include` in the shipped terminal config, `hyprland.lua` through Hyprland's Lua
|
||||
module path, `shell.toml` and `chromium.theme` read straight from the state
|
||||
directory, and `btop.theme`, `neovim.lua` and `gtk.css` through symlinks the
|
||||
installer makes into those apps' own config trees.
|
||||
directory, and `btop.theme`, `neovim.lua`, `gtk.css` and `starship.toml`
|
||||
through symlinks the installer makes into those apps' own config trees.
|
||||
|
||||
`default/themed/*.tpl` are rendered per theme into
|
||||
`~/.local/state/blob/current/theme/`. Ten ship: foot, kitty, btop, chromium,
|
||||
hyprland, the screenshare picker, neovim, `shell.toml`, zen, and `gtk.css`.
|
||||
`~/.local/state/blob/current/theme/`. Eleven ship: foot, kitty, btop, chromium,
|
||||
hyprland, the screenshare picker, neovim, `shell.toml`, zen, `gtk.css`, and
|
||||
`starship.toml`.
|
||||
|
||||
An app picks its colors up in one of two ways. Most include the generated file
|
||||
directly, so nothing has to run:
|
||||
@@ -65,6 +66,20 @@ so an app that was already open keeps its old colors until it is restarted.
|
||||
Adding a template for another app means dropping a `.tpl` in `default/themed/`
|
||||
and, if it cannot include a file, adding an applier to that list.
|
||||
|
||||
## The prompt
|
||||
|
||||
`starship.toml` is linked to `~/.config/starship.toml`. It carries a
|
||||
`[palettes.blob]` block built from the theme - `accent`, `foreground`, `muted`,
|
||||
`success`, `warning`, `error` - and every style in the file names one of those
|
||||
rather than a literal color, so the prompt moves with the theme. Starship reads
|
||||
its config on each prompt, so a theme change shows up on the next command, in
|
||||
shells that are already open.
|
||||
|
||||
`starship init bash` runs from `session/bashrc`, which `install.sh` sources from
|
||||
`~/.bashrc` with a single line. That file returns immediately in a
|
||||
non-interactive shell, so it cannot disturb `scp` or `rsync`, and it also
|
||||
sources `session/env-bootstrap` so `blob` is on `PATH` in any interactive shell.
|
||||
|
||||
## The three ways to set a theme
|
||||
|
||||
| Command | Does |
|
||||
|
||||
@@ -63,7 +63,9 @@ link_blob_path
|
||||
install_packages
|
||||
|
||||
install_shipped_config
|
||||
refresh_font_cache
|
||||
install_shell_profile
|
||||
install_bash_integration
|
||||
install_user_units
|
||||
install_systemd_dropins
|
||||
install_zen_config
|
||||
|
||||
@@ -63,6 +63,42 @@ install_shipped_config() {
|
||||
install_file "$repo_dir/fonts/omarchy.ttf" "$font_dir/omarchy.ttf" "fonts/omarchy.ttf"
|
||||
}
|
||||
|
||||
bashrc_line='[ -r "$HOME/.local/share/blob/session/bashrc" ] && . "$HOME/.local/share/blob/session/bashrc"'
|
||||
|
||||
install_bash_integration() {
|
||||
local bashrc="$HOME/.bashrc"
|
||||
|
||||
if [[ -f $bashrc ]] && grep -Fqx "$bashrc_line" "$bashrc"; then
|
||||
say "ok bashrc"
|
||||
return 0
|
||||
fi
|
||||
|
||||
note_change
|
||||
if [[ $check == true ]]; then
|
||||
say "would source session/bashrc from ~/.bashrc"
|
||||
return 0
|
||||
fi
|
||||
|
||||
[[ -f $bashrc ]] && cp "$bashrc" "$bashrc.bak"
|
||||
printf '\n%s\n' "$bashrc_line" >>"$bashrc"
|
||||
say "write bashrc"
|
||||
}
|
||||
|
||||
refresh_font_cache() {
|
||||
if ! command -v fc-cache &>/dev/null; then
|
||||
say "SKIP font cache (fc-cache not installed)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ $check == true ]]; then
|
||||
say "would refresh the font cache"
|
||||
return 0
|
||||
fi
|
||||
|
||||
fc-cache -f "$font_dir" >/dev/null 2>&1 || true
|
||||
say "ok font cache"
|
||||
}
|
||||
|
||||
install_shell_profile() {
|
||||
install_root_file "$repo_dir/session/profile.sh" /etc/profile.d/blob.sh "profile.d/blob.sh"
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ install_login_config() {
|
||||
"$blob_greeter_conf" "sddm.conf.d/zz-blob.conf"
|
||||
install_root_file "$repo_dir/bin/blob-hw-gpu-accelerated" \
|
||||
"$greeter_gpu_detector" "blob-hw-gpu-accelerated" 0755
|
||||
install_root_file "$repo_dir/default/pam.d/blob-lock-password" \
|
||||
/etc/pam.d/blob-lock-password "pam.d/blob-lock-password"
|
||||
}
|
||||
|
||||
install_session_entry() {
|
||||
|
||||
@@ -133,6 +133,7 @@ link_app_themes() {
|
||||
link_theme_file btop.theme "$config_dir/btop/themes/current.theme" "btop theme"
|
||||
link_theme_file gtk.css "$config_dir/gtk-3.0/gtk.css" "gtk-3.0 theme"
|
||||
link_theme_file gtk.css "$config_dir/gtk-4.0/gtk.css" "gtk-4.0 theme"
|
||||
link_theme_file starship.toml "$config_dir/starship.toml" "starship prompt"
|
||||
|
||||
if [[ -d $config_dir/nvim/lua/plugins ]]; then
|
||||
link_theme_file neovim.lua "$config_dir/nvim/lua/plugins/theme.lua" "neovim theme"
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
# Palette extraction behind blob-wallpaper-set; pywal16 is the maintained fork
|
||||
python-pywal16|python-pywal
|
||||
|
||||
# Terminal text effects behind the screensaver; ttfx was the Omarchy build
|
||||
python-terminaltexteffects
|
||||
|
||||
# Terminal dispatch; every TUI launcher's Exec= line calls it
|
||||
xdg-terminal-exec
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
case $- in
|
||||
*i*) ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
|
||||
[ -r "$HOME/.local/share/blob/session/env-bootstrap" ] && . "$HOME/.local/share/blob/session/env-bootstrap"
|
||||
|
||||
command -v starship >/dev/null 2>&1 && eval "$(starship init bash)"
|
||||
@@ -15,6 +15,13 @@ Item {
|
||||
|
||||
readonly property string pluginId: (manifest && manifest.id) || "blob.quick-settings"
|
||||
|
||||
readonly property int barInset: {
|
||||
var bar = root.shell ? root.shell.bar : null
|
||||
if (!bar || bar.barHidden === true) return 0
|
||||
if (String(bar.position || "top") !== "top") return 0
|
||||
return Math.max(0, bar.barSize || 0)
|
||||
}
|
||||
|
||||
function open(payloadJson) {
|
||||
root.opened = true
|
||||
}
|
||||
@@ -187,7 +194,7 @@ Item {
|
||||
|
||||
Row {
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.spaceReal(10)
|
||||
anchors.topMargin: Style.spaceReal(10) + root.barInset
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: Style.spaceReal(12)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ session_entry="/usr/local/share/wayland-sessions/blob.desktop"
|
||||
root_files=(
|
||||
/etc/profile.d/blob.sh
|
||||
/usr/local/bin/blob-hw-gpu-accelerated
|
||||
/etc/pam.d/blob-lock-password
|
||||
/etc/sddm.conf.d/zz-blob.conf
|
||||
/etc/sddm.conf.d/zzz-blob-autologin.conf
|
||||
/etc/sddm/hyprland-greeter.conf
|
||||
@@ -112,6 +113,8 @@ for lua in hyprland.lua monitors.lua input.lua looknfeel.lua bindings.lua autost
|
||||
restore_or_remove "$config_dir/hypr/$lua" "hypr/$lua"
|
||||
done
|
||||
|
||||
[[ -L $config_dir/starship.toml ]] && restore_or_remove "$config_dir/starship.toml" "starship.toml"
|
||||
|
||||
for gtk in gtk-3.0 gtk-4.0; do
|
||||
[[ -L $config_dir/$gtk/gtk.css ]] && restore_or_remove "$config_dir/$gtk/gtk.css" "$gtk/gtk.css"
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user