#!/bin/bash # omarchy:summary=Give terminals, btop, and GTK apps a see-through background while windows are glassy # omarchy:args=[theme-dir] # omarchy:hidden=true # A Hyprland opacity rule fades a terminal's text along with its background, # and foot turns compositor blur down unless its own config asks for it, so the # glass belongs in each terminal's theme file, as in the glassy Starship # (#14726). The lines sit between markers so leaving glassy takes them out # again, and a theme that sets its own opacity keeps it. THEME_DIR="${1:-$HOME/.local/state/omarchy/current/theme}" TOGGLES_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy/toggles/hypr" GLASSY=false [[ -f $TOGGLES_DIR/window-glassy.lua ]] && GLASSY=true status=0 # A literal for a sed address, whose delimiter is /. regex() { sed 's/[][\\.*^$/]/\\&/g' <<<"$1" } # A block added to a file that did not end in a newline has to supply one, so # its begin marker says so, and taking the block out takes that newline back. # Leaving glassy then gives the file back exactly as it was. Markers come as # an opening and a closing part, so CSS can wrap them in a comment. remove_block() { local file="$1" open="$2" close="$3" local begin end begin=$(regex "$open omarchy-glass begin") end=$(regex "$open omarchy-glass end$close") [[ -f $file ]] && grep -qF "$open omarchy-glass begin" "$file" || return 0 local added_newline=false grep -qxF "$open omarchy-glass begin after a line without a newline$close" "$file" && added_newline=true sed -i "/^$begin/,/^$end\$/d" "$file" || return 1 if [[ $added_newline == "true" && -s $file && -z $(tail -c 1 "$file") ]]; then truncate -s -1 "$file" || return 1 fi } append_block() { local file="$1" open="$2" close="$3" lines="$4" if [[ -s $file && -n $(tail -c 1 "$file") ]]; then printf '\n%s\n%s\n%s\n' "$open omarchy-glass begin after a line without a newline$close" "$lines" "$open omarchy-glass end$close" >>"$file" else printf '%s\n%s\n%s\n' "$open omarchy-glass begin$close" "$lines" "$open omarchy-glass end$close" >>"$file" fi } # Each setting comes with a pattern for the theme setting it already, which # keeps the theme's own; an empty pattern always adds it. Lines that belong in # a section go in under its header. A file that already has the section gets # them inside it, since TOML refuses a table declared twice; otherwise the # header comes along with them. glass() { local file="$THEME_DIR/$1" section="$2" shift 2 [[ -f $file ]] || return 0 remove_block "$file" "#" "" || return 1 [[ $GLASSY == "true" ]] || return 0 local lines="" while (( $# >= 2 )); do if [[ -z $1 ]] || ! grep -qE "$1" "$file"; then lines+="${lines:+$'\n'}$2" fi shift 2 done [[ -n $lines ]] || return 0 # A header may carry trailing space or a comment. local header="^$(regex "$section")[[:space:]]*(#.*)?\$" if [[ -n $section ]] && grep -qE "$header" "$file"; then local block block=$(mktemp) || return 1 printf '# omarchy-glass begin\n%s\n# omarchy-glass end\n' "$lines" >"$block" sed -i -E "0,/$header/{/$header/r $block }" "$file" local result=$? rm -f "$block" return $result fi append_block "$file" "#" "" "${section:+$section$'\n'}$lines" } # Alacritty's own blur works only on macOS and KDE; Hyprland blurs it anyway. glass alacritty.toml '[window]' \ '^[[:space:]]*opacity[[:space:]]*=' 'opacity = 0.65' || status=1 glass foot.ini '[colors-dark]' \ '^[[:space:]]*alpha[[:space:]]*=' 'alpha=0.65' \ '^[[:space:]]*blur[[:space:]]*=' 'blur=yes' || status=1 glass kitty.conf '' \ '^[[:space:]]*background_opacity[[:space:]]' 'background_opacity 0.65' || status=1 # btop paints its own background over the terminal's glass. An empty main_bg # uses the terminal background; the last theme value wins, so removing the # block restores the theme's colour without changing btop's user config. glass btop.theme '' \ '^[[:space:]]*theme\[main_bg\][[:space:]]*=[[:space:]]*""' 'theme[main_bg]=""' || status=1 # GTK only asks Hyprland for blur under a CSS backdrop-filter, which Ghostty # takes as custom CSS and reloads live; its background-blur speaks only KDE's # blur protocol. glass ghostty.conf '' \ '^[[:space:]]*background-opacity[[:space:]]*=' 'background-opacity = 0.65' \ '' "gtk-custom-css = $OMARCHY_PATH/default/gtk/glass.css" || status=1 # Other GTK apps, such as Nautilus, read the user's gtk.css at launch, so the # same backdrop blur is imported there. It follows the mode alone, so a theme # switch, which names the theme it is rendering, leaves it be. if (( $# == 0 )); then gtk_css="${XDG_CONFIG_HOME:-$HOME/.config}/gtk-4.0/gtk.css" remove_block "$gtk_css" "/*" " */" || status=1 if [[ $GLASSY == "true" ]]; then { mkdir -p "${gtk_css%/*}" && append_block "$gtk_css" "/*" " */" "@import url(\"file://$OMARCHY_PATH/default/gtk/glass.css\");"; } || status=1 fi fi exit $status