Pick window transparency from Appearance > Window Transparency, and a Glassy bar background (#14991)
* Pick window transparency from Appearance > Window Transparency Transparent, the default, keeps today's windows. Opaque turns the windows Omarchy makes transparent solid. Glassy is the frosted glass Starship (#14726): its blur behind every see-through window and shell surface, and a see-through, blurred background in the theme's terminal files, since foot turns compositor blur down and a Hyprland opacity rule fades text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Leave window transparency to Appearance when animations are off Turning animations off no longer makes windows opaque. VM installs start with opaque windows instead, and a migration keeps them opaque for anyone who already has animations off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Add a Glassy bar background, under Menu Bar > Bar Background Menu Bar > Bar Background picks Opaque Bar, Glassy Bar or Clear Bar, and Indicators becomes Bar Indicators to match. Glassy keeps the theme background faintly and Hyprland blurs what is behind it, with the same blur as Glassy windows. omarchy bar background opaque|glassy|none|cycle sets it and prints it when given nothing. omarchy bar transparent true|false|toggle stays for compatibility, as none and opaque. Double-clicking the bar cycles through the three backgrounds the same way, from clear to glassy to opaque. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Stop when a saved corner choice can't be removed Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Make btop follow glassy windows --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
be7c7bf378
commit
a98e55eb91
32 files changed
+814
-64
No files matched your search
+77
-7
@@ -2,7 +2,7 @@
|
||||
|
||||
# omarchy:summary=Configure the bar and its widget layout
|
||||
# omarchy:group=bar
|
||||
# omarchy:args=use <id> | reset | defaults | position [top|bottom|left|right] | transparent <true|false|toggle> | put <id> [placement] | move <id> [placement] | set <id> <key> <value> [--json] [placement] | get <id> <key>
|
||||
# omarchy:args=use <id> | reset | defaults | position [top|bottom|left|right] | background [opaque|glassy|none|cycle] | put <id> [placement] | move <id> [placement] | set <id> <key> <value> [--json] [placement] | get <id> <key>
|
||||
# omarchy:examples=omarchy bar use local.neon-bar | omarchy bar put omarchy.keyboard-layout --after omarchy.clock | omarchy bar move omarchy.clock --section center --index 0 | omarchy bar set omarchy.clock format HH:mm
|
||||
|
||||
set -euo pipefail
|
||||
@@ -18,7 +18,11 @@ Usage: omarchy bar <command> [args...]
|
||||
defaults Restore the default bar and service widgets
|
||||
position [top|bottom|left|right] Bar position; prints the current one
|
||||
when given none
|
||||
transparent <true|false|toggle> Bar transparency
|
||||
background [opaque|glassy|none|cycle]
|
||||
Bar background: glassy shows what is
|
||||
behind the bar blurred, cycle steps
|
||||
none, glassy, opaque; prints the
|
||||
current one when given none
|
||||
put <id> [placement] Put a widget on the bar, leaving one
|
||||
that is already there where it is
|
||||
move <id> [placement] Move a widget within or between sections
|
||||
@@ -194,6 +198,7 @@ cmd_defaults() {
|
||||
" \
|
||||
--slurpfile defaults "$DEFAULTS_FILE" \
|
||||
--argjson widgets "$optional_widgets"
|
||||
sync_glass || fail "could not change the blur behind the bar"
|
||||
echo "Restored the default Omarchy bar"
|
||||
}
|
||||
|
||||
@@ -210,18 +215,75 @@ cmd_position() {
|
||||
echo "Bar position set to $position"
|
||||
}
|
||||
|
||||
# The bar background is opaque, glassy, or none. A shell.json from before it
|
||||
# had one says transparent instead, which is none, and setting a background
|
||||
# drops it.
|
||||
current_background() {
|
||||
jq -r '.bar.background // (if .bar.transparent == true then "none" else "opaque" end)' "$(source_file)"
|
||||
}
|
||||
|
||||
cmd_background() {
|
||||
if (( $# == 0 )); then
|
||||
current_background
|
||||
return
|
||||
fi
|
||||
|
||||
local background="$1"
|
||||
(( $# == 1 )) || fail "background takes a single value"
|
||||
[[ $background =~ ^(opaque|glassy|none|cycle)$ ]] || fail "background must be opaque, glassy, none, or cycle"
|
||||
|
||||
if [[ $background == "cycle" ]]; then
|
||||
# Each step changes the bar by one degree: clear, then glassy, then opaque.
|
||||
case $(current_background) in
|
||||
none) background="glassy" ;;
|
||||
glassy) background="opaque" ;;
|
||||
*) background="none" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
local previous
|
||||
previous=$(current_background)
|
||||
commit "$NORMALIZE | .bar.background = \$background | del(.bar.transparent)" --arg background "$background"
|
||||
if ! sync_glass; then
|
||||
commit "$NORMALIZE | .bar.background = \$background | del(.bar.transparent)" --arg background "$previous"
|
||||
fail "could not change the blur behind the bar"
|
||||
fi
|
||||
echo "Bar background set to $background"
|
||||
}
|
||||
|
||||
# The older on/off form of the background, kept for scripts and dotfiles:
|
||||
# transparent is none, and not transparent is opaque.
|
||||
cmd_transparent() {
|
||||
local transparent="${1:-}"
|
||||
[[ -n $transparent ]] || fail "transparent is required"
|
||||
(( $# == 1 )) || fail "transparent takes a single value"
|
||||
[[ $transparent =~ ^(true|false|toggle)$ ]] || fail "transparent must be true, false, or toggle"
|
||||
if [[ $transparent == "toggle" ]]; then
|
||||
commit "$NORMALIZE | .bar.transparent = (.bar.transparent != true)"
|
||||
echo "Bar transparency toggled"
|
||||
else
|
||||
commit "$NORMALIZE | .bar.transparent = \$transparent" --argjson transparent "$transparent"
|
||||
echo "Bar transparency set to $transparent"
|
||||
[[ $(current_background) == "none" ]] && transparent="false" || transparent="true"
|
||||
fi
|
||||
if [[ $transparent == "true" ]]; then
|
||||
cmd_background none
|
||||
else
|
||||
cmd_background opaque
|
||||
fi
|
||||
}
|
||||
|
||||
# Hyprland blurs behind the bar only while the bar-glassy toggle is on, so it
|
||||
# follows the bar background, reloading Hyprland only when it changes. The
|
||||
# toggle sits where Hyprland reads it, under XDG_STATE_HOME.
|
||||
sync_glass() {
|
||||
local dir="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy/toggles/hypr"
|
||||
local flag="$dir/bar-glassy.lua"
|
||||
|
||||
if [[ $(current_background) == "glassy" ]]; then
|
||||
[[ ! -f $flag ]] || return 0
|
||||
mkdir -p "$dir" && cp "$OMARCHY_PATH/default/hypr/toggles/bar-glassy.lua" "$flag" || return 1
|
||||
else
|
||||
[[ -f $flag ]] || return 0
|
||||
rm -f "$flag" || return 1
|
||||
fi
|
||||
|
||||
hyprctl reload >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
bar_widget_default_section() {
|
||||
@@ -406,6 +468,14 @@ case "$command" in
|
||||
transparent)
|
||||
cmd_transparent "$@"
|
||||
;;
|
||||
background)
|
||||
cmd_background "$@"
|
||||
;;
|
||||
# Internal: the shell runs this when it loads a bar background, so one set
|
||||
# by editing shell.json gets its blur too.
|
||||
sync-glass)
|
||||
sync_glass || fail "could not change the blur behind the bar"
|
||||
;;
|
||||
put)
|
||||
cmd_put "$@"
|
||||
;;
|
||||
|
||||
@@ -34,7 +34,7 @@ if [[ $1 != "theme" ]]; then
|
||||
mkdir -p "$TOGGLES_DIR" && cp "$OMARCHY_PATH/default/hypr/toggles/corners-$1.lua" "$TOGGLES_DIR/corners-$1.lua" || exit 1
|
||||
fi
|
||||
for mode in sharp rounded; do
|
||||
[[ $mode == "$1" ]] || rm -f "$TOGGLES_DIR/corners-$mode.lua"
|
||||
[[ $mode == "$1" ]] || rm -f "$TOGGLES_DIR/corners-$mode.lua" || exit 1
|
||||
done
|
||||
|
||||
hyprctl reload >/dev/null || exit 1
|
||||
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Show or set how see-through windows are: opaque, transparent, or glassy
|
||||
# omarchy:args=[opaque|transparent|glassy]
|
||||
# omarchy:examples=omarchy hyprland window transparency | omarchy hyprland window transparency glassy
|
||||
|
||||
TOGGLES_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy/toggles/hypr"
|
||||
|
||||
# Opaque and glassy are toggle files loaded after every theme: opaque makes the
|
||||
# windows Omarchy makes transparent solid, and glassy blurs what is behind any
|
||||
# see-through window and gives terminals a see-through background. Transparent,
|
||||
# the default, removes both.
|
||||
current_mode() {
|
||||
if [[ -f $TOGGLES_DIR/window-opaque.lua ]]; then
|
||||
echo "opaque"
|
||||
elif [[ -f $TOGGLES_DIR/window-glassy.lua ]]; then
|
||||
echo "glassy"
|
||||
else
|
||||
echo "transparent"
|
||||
fi
|
||||
}
|
||||
|
||||
# Save the new choice before dropping the old one, so a failed save keeps it.
|
||||
save_mode() {
|
||||
if [[ $1 != "transparent" ]]; then
|
||||
mkdir -p "$TOGGLES_DIR" && cp "$OMARCHY_PATH/default/hypr/toggles/window-$1.lua" "$TOGGLES_DIR/window-$1.lua" || return 1
|
||||
fi
|
||||
local mode
|
||||
for mode in opaque glassy; do
|
||||
[[ $mode == "$1" ]] || rm -f "$TOGGLES_DIR/window-$mode.lua" || return 1
|
||||
done
|
||||
}
|
||||
|
||||
if (( $# == 0 )); then
|
||||
current_mode
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
opaque) LABEL="Opaque windows" ;;
|
||||
transparent) LABEL="Transparent windows" ;;
|
||||
glassy) LABEL="Glassy windows" ;;
|
||||
*)
|
||||
echo "Usage: omarchy-hyprland-window-transparency [opaque|transparent|glassy]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# A theme switch renders the next theme's terminal files from the saved choice
|
||||
# and then replaces the current theme, so the choice and the glass written into
|
||||
# the current theme are changed under its lock, or the switch could drop them.
|
||||
exec 9>"${XDG_RUNTIME_DIR:-/tmp}/omarchy-theme-set.lock"
|
||||
flock 9
|
||||
|
||||
# A choice whose glass cannot be written is taken back, so the saved choice
|
||||
# is always the one on screen.
|
||||
previous=$(current_mode)
|
||||
save_mode "$1" || exit 1
|
||||
if ! omarchy-theme-set-glass; then
|
||||
save_mode "$previous"
|
||||
omarchy-theme-set-glass
|
||||
exit 1
|
||||
fi
|
||||
flock -u 9
|
||||
|
||||
hyprctl reload >/dev/null || exit 1
|
||||
omarchy-restart-terminal
|
||||
omarchy-theme-set-foot
|
||||
omarchy-restart-btop
|
||||
omarchy-notification-send -g "$LABEL"
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Apply current Omarchy theme colors to running Foot terminals
|
||||
# omarchy:summary=Apply current Omarchy theme colors and background alpha to running Foot terminals
|
||||
# omarchy:hidden=true
|
||||
|
||||
colors_toml=$HOME/.local/state/omarchy/current/theme/colors.toml
|
||||
foot_ini=$HOME/.local/state/omarchy/current/theme/foot.ini
|
||||
|
||||
if [[ ! -f $colors_toml ]] || ! pgrep -x foot >/dev/null; then
|
||||
exit 0
|
||||
@@ -12,6 +13,16 @@ fi
|
||||
foot_osc=$(omarchy-theme-osc "$colors_toml")
|
||||
[[ -n $foot_osc ]] || exit 0
|
||||
|
||||
# foot takes a background alpha as an urxvt-style [percent] prefix, so a theme
|
||||
# going see-through or back, as with Glassy windows, reaches running terminals.
|
||||
# The last alpha in the theme's foot.ini wins, as it does when foot reads it.
|
||||
alpha=$(sed -n 's/^[[:space:]]*alpha[[:space:]]*=[[:space:]]*\([0-9.]*\).*/\1/p' "$foot_ini" 2>/dev/null | tail -n 1)
|
||||
background=$(omarchy-theme-color --file "$colors_toml" background 2>/dev/null)
|
||||
if [[ -n $background ]]; then
|
||||
percent=$(awk -v alpha="${alpha:-1}" 'BEGIN { printf "%d", alpha * 100 + 0.5 }')
|
||||
foot_osc+=$(printf '\033]11;[%d]%s\007' "$percent" "$background")
|
||||
fi
|
||||
|
||||
for foot_pid in $(pgrep -x foot); do
|
||||
for child_pid in $(pgrep -P "$foot_pid"); do
|
||||
tty=$(readlink "/proc/$child_pid/fd/1" 2>/dev/null)
|
||||
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/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
|
||||
@@ -451,3 +451,4 @@ if [[ -f $COLORS_FILE ]]; then
|
||||
fi
|
||||
|
||||
apply_shell_section_overrides
|
||||
omarchy-theme-set-glass "$NEXT_THEME_DIR"
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Toggle animations, transparency and other effects that are slow without a GPU
|
||||
# omarchy:summary=Toggle animations, blur and shadows, which are slow without a GPU
|
||||
# omarchy:args=[toggle|on|off]
|
||||
# omarchy:examples=omarchy toggle animations | omarchy toggle animations off | omarchy toggle animations on
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
},
|
||||
"bar": {
|
||||
"position": "top",
|
||||
"transparent": false,
|
||||
"background": "opaque",
|
||||
"centerAnchor": "omarchy.clock",
|
||||
"layout": {
|
||||
"left": [
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/* GTK asks the compositor to blur behind a see-through window only where a
|
||||
backdrop-filter blur covers it, so Glassy windows load this into GTK apps,
|
||||
such as Ghostty and Nautilus. The compositor's own blur settings decide
|
||||
how it looks. */
|
||||
window {
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
-- Frosted glass from the glassy Starship (#14726), shared by Glassy windows and
|
||||
-- the Glassy bar: whatever is behind a see-through surface is blurred.
|
||||
return function()
|
||||
hl.config({
|
||||
decoration = {
|
||||
blur = {
|
||||
enabled = true,
|
||||
size = 4,
|
||||
passes = 2,
|
||||
new_optimizations = true,
|
||||
xray = false,
|
||||
contrast = 1.0,
|
||||
brightness = 0.75,
|
||||
noise = 0.01,
|
||||
vibrancy = 0.35,
|
||||
vibrancy_darkness = 0.35,
|
||||
popups = true,
|
||||
special = true,
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
@@ -281,7 +281,8 @@ function o.window(match, rules)
|
||||
hl.window_rule(rules)
|
||||
end
|
||||
|
||||
-- Opt a window in to Omarchy's standard active/inactive transparency.
|
||||
-- Opt a window in to Omarchy's standard active/inactive transparency. The tag
|
||||
-- lets Appearance > Window Transparency turn these windows opaque or glassy.
|
||||
function o.transparent_window(match, opacity)
|
||||
o.window(match, { opacity = opacity or "0.985 0.96" })
|
||||
o.window(match, { opacity = opacity or "0.985 0.96", tag = "+transparent-window" })
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
-- The Glassy bar: the shell draws the bar see-through, and Hyprland blurs what
|
||||
-- is behind it.
|
||||
require("default.hypr.glass")()
|
||||
|
||||
hl.layer_rule({
|
||||
match = { namespace = "^omarchy-bar$" },
|
||||
blur = true,
|
||||
ignore_alpha = 0.3,
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
-- Draw nothing just for show, for machines that render on the CPU, like a VM:
|
||||
-- no animations, blur or shadows, and opaque windows, so nothing behind a
|
||||
-- window has to be blended into it.
|
||||
-- no animations, blur or shadows. How see-through windows are is left to
|
||||
-- Appearance > Window Transparency.
|
||||
hl.config({
|
||||
animations = {
|
||||
enabled = false,
|
||||
@@ -16,5 +16,3 @@ hl.config({
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
o.window(".*", { opacity = "1 1" })
|
||||
@@ -0,0 +1,14 @@
|
||||
-- Frosted glass from the glassy Starship (#14726): whatever is behind a
|
||||
-- see-through window or shell surface is blurred. Terminals get the see-through
|
||||
-- background itself from omarchy-theme-set-glass, which keeps their text crisp.
|
||||
require("default.hypr.glass")()
|
||||
|
||||
-- GTK apps fade as a whole, since GTK draws their backgrounds solid, and get
|
||||
-- their blur from the backdrop-filter Glassy adds to the user's gtk.css.
|
||||
o.window("org\\.gnome\\.Nautilus", { opacity = "0.75 0.75" })
|
||||
|
||||
hl.layer_rule({
|
||||
match = { namespace = "^(omarchy-bar|omarchy-menu|omarchy-notifications|omarchy-osd|omarchy-polkit|omarchy-reminders|omarchy-clipboard|omarchy-emojis|omarchy-image-selector|omarchy-keyboard-panel|omarchy-network-qr)$" },
|
||||
blur = true,
|
||||
ignore_alpha = 0.3,
|
||||
})
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Opaque windows, even those Omarchy makes transparent by default.
|
||||
o.window({ tag = "transparent-window" }, { opacity = "1 1" })
|
||||
@@ -59,9 +59,11 @@
|
||||
"trigger.appearance.top-bar.hide": {"icon":"","label":"Hide Bar","when":"! omarchy-toggle-enabled bar-off","action":"omarchy-toggle-bar"},
|
||||
"trigger.appearance.top-bar.show": {"icon":"","label":"Show Bar","when":"omarchy-toggle-enabled bar-off","action":"omarchy-toggle-bar"},
|
||||
"trigger.appearance.top-bar.position": {"icon":"","label":"Position Bar"},
|
||||
"trigger.appearance.top-bar.transparent": {"icon":"","label":"Transparent Bar","when":"! jq -e .bar.transparent ~/.config/omarchy/shell.json >/dev/null 2>&1","action":"omarchy-bar transparent true"},
|
||||
"trigger.appearance.top-bar.opaque": {"icon":"","label":"Opaque Bar","when":"jq -e .bar.transparent ~/.config/omarchy/shell.json >/dev/null 2>&1","action":"omarchy-bar transparent false"},
|
||||
"trigger.appearance.top-bar.indicators": {"icon":"","label":"Indicators"},
|
||||
"trigger.appearance.top-bar.background": {"icon":"","label":"Bar Background"},
|
||||
"trigger.appearance.top-bar.background.opaque": {"icon":"","label":"Opaque Bar","checked":"[[ $(omarchy-bar background) == \"opaque\" ]]","action":"omarchy-bar background opaque"},
|
||||
"trigger.appearance.top-bar.background.glassy": {"icon":"","label":"Glassy Bar","checked":"[[ $(omarchy-bar background) == \"glassy\" ]]","action":"omarchy-bar background glassy"},
|
||||
"trigger.appearance.top-bar.background.clear": {"icon":"","label":"Clear Bar","checked":"[[ $(omarchy-bar background) == \"none\" ]]","action":"omarchy-bar background none"},
|
||||
"trigger.appearance.top-bar.indicators": {"icon":"","label":"Bar Indicators"},
|
||||
"trigger.appearance.top-bar.indicators.battery-percentage": {"icon":"","label":"Battery Percentage","when":"omarchy-hw-laptop","action":"omarchy-shell omarchy.power togglePercentage"},
|
||||
"trigger.appearance.top-bar.indicators.clock": {"icon":"","label":"Clock"},
|
||||
"trigger.appearance.top-bar.indicators.clock.sunday-24h": {"icon":"","label":"Sunday 14:30","when":"[[ $(omarchy-bar position) != \"left\" && $(omarchy-bar position) != \"right\" ]]","checked":"[[ $(omarchy-bar get omarchy.clock format) == \"dddd HH:mm\" ]]","action":"omarchy-bar set omarchy.clock format \"dddd HH:mm\""},
|
||||
@@ -87,6 +89,10 @@
|
||||
"trigger.appearance.window-corners.theme": {"icon":"","label":"Theme Corners","checked":"[[ $(omarchy-hyprland-corners) == \"theme\" ]]","action":"omarchy-hyprland-corners theme"},
|
||||
"trigger.appearance.window-corners.sharp": {"icon":"","label":"Sharp Corners","checked":"[[ $(omarchy-hyprland-corners) == \"sharp\" ]]","action":"omarchy-hyprland-corners sharp"},
|
||||
"trigger.appearance.window-corners.rounded": {"icon":"","label":"Rounded Corners","checked":"[[ $(omarchy-hyprland-corners) == \"rounded\" ]]","action":"omarchy-hyprland-corners rounded"},
|
||||
"trigger.appearance.window-transparency": {"icon":"","label":"Window Transparency"},
|
||||
"trigger.appearance.window-transparency.opaque": {"icon":"","label":"Opaque Windows","checked":"[[ $(omarchy-hyprland-window-transparency) == \"opaque\" ]]","action":"omarchy-hyprland-window-transparency opaque"},
|
||||
"trigger.appearance.window-transparency.transparent": {"icon":"","label":"Transparent Windows","checked":"[[ $(omarchy-hyprland-window-transparency) == \"transparent\" ]]","action":"omarchy-hyprland-window-transparency transparent"},
|
||||
"trigger.appearance.window-transparency.glassy": {"icon":"","label":"Glassy Windows","checked":"[[ $(omarchy-hyprland-window-transparency) == \"glassy\" ]]","action":"omarchy-hyprland-window-transparency glassy"},
|
||||
"trigger.appearance.one-window-ratio": {"icon":"","label":"1-Window Ratio","action":"omarchy-hyprland-window-single-square-aspect-toggle"},
|
||||
"trigger.appearance.workspace-layout": {"icon":"","label":"Workspace Layout","title":"Default Workspace Layout"},
|
||||
"trigger.appearance.workspace-layout.dwindle": {"icon":"","label":"Tiling","checked":"[[ $(omarchy-hyprland-workspace-layout-default) == \"dwindle\" ]]","action":"omarchy-hyprland-workspace-layout-default dwindle"},
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
[colors-dark]
|
||||
foreground={{ foreground_strip }}
|
||||
background={{ background_strip }}
|
||||
# Blur only applies while the background is see-through, as with Glassy windows,
|
||||
# and foot reads it only at launch, so it is on from the start.
|
||||
blur=yes
|
||||
selection-foreground={{ selection_foreground_strip }}
|
||||
selection-background={{ selection_background_strip }}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ selection_background {{ selection_background }}
|
||||
cursor {{ bright_foreground }}
|
||||
cursor_text_color {{ background }}
|
||||
|
||||
# Lets a reload change the background opacity, as Glassy windows do, since
|
||||
# kitty only allows that when this is on from launch.
|
||||
dynamic_background_opacity yes
|
||||
|
||||
active_border_color {{ accent }}
|
||||
active_tab_background {{ accent }}
|
||||
|
||||
|
||||
@@ -94,8 +94,8 @@ You can still install by hand: drop a plugin into
|
||||
`~/.config/omarchy/plugins/<id>/`, run `omarchy-shell shell rescanPlugins`, then
|
||||
`omarchy plugin enable <id>`. A bar widget starts in its declared default
|
||||
section; enabling a full bar replaces the one in use. `omarchy bar` drives the
|
||||
bar from the CLI — `use | reset | defaults | position | transparent | put |
|
||||
move | set`, with placement flags such as `--section` and `--index`.
|
||||
bar from the CLI — `use | reset | defaults | position | background | put |
|
||||
move | set | get`, with placement flags such as `--section` and `--index`.
|
||||
The lower-level IPC methods remain available through `omarchy-shell shell ...`.
|
||||
|
||||
## Elsewhen
|
||||
@@ -121,7 +121,7 @@ or `omarchy.power`. There is no `bar` target.
|
||||
| `rescanPlugins` | re-walk plugin dirs and hot-reload plugin code |
|
||||
| `reloadConfig` | reload shell.json |
|
||||
| `applyTheme <colorsB64> <shellB64>` | push theme colors + shell.toml |
|
||||
| `toggleBarTransparency` | flip the bar background between solid and transparent |
|
||||
| `toggleBarTransparency` | cycle the bar background from clear to glassy to opaque |
|
||||
| `cycleInput <next\|back>` | switch to the next or previous input method or layout (Super+I, Super+Shift+I); `not running` without the input reader |
|
||||
| `setPluginEnabled <id> <"true"\|…>` | flip enabled bit (`ok` / `unknown`) |
|
||||
| `enablePlugin <id> <placementJson>` | enable and place in one mutation |
|
||||
@@ -148,7 +148,7 @@ string on a miss.
|
||||
"bar": {
|
||||
"id": "omarchy.bar",
|
||||
"position": "top",
|
||||
"transparent": false,
|
||||
"background": "opaque",
|
||||
"centerAnchor": "omarchy.clock",
|
||||
"layout": {
|
||||
"left": [ { "id": "omarchy.menu" } ],
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# A VM usually renders on the CPU, where animations and transparency cost
|
||||
# every frame, so start it without them. omarchy-toggle-animations brings them
|
||||
# back. This runs before any Hyprland session exists, so place the flag
|
||||
# directly rather than through omarchy-hyprland-toggle, which reloads Hyprland.
|
||||
# every frame, so start it without them and with opaque windows.
|
||||
# omarchy-toggle-animations and Appearance > Window Transparency bring them
|
||||
# back. This runs before any Hyprland session exists, so place the flags
|
||||
# directly rather than through the commands, which reload Hyprland.
|
||||
if omarchy-hw-vm; then
|
||||
echo "Detected a virtual machine. Turning off animations and transparency."
|
||||
mkdir -p "$HOME/.local/state/omarchy/toggles/hypr"
|
||||
cp "$OMARCHY_PATH/default/hypr/toggles/no-animations.lua" "$HOME/.local/state/omarchy/toggles/hypr/"
|
||||
cp "$OMARCHY_PATH/default/hypr/toggles/window-opaque.lua" "$HOME/.local/state/omarchy/toggles/hypr/"
|
||||
fi
|
||||
@@ -81,15 +81,15 @@ If you'd rather they were always visible, set `alwaysShow` to `true` on the widg
|
||||
|
||||
The bar configures itself. You don't have to open a config file to move things.
|
||||
|
||||
Grab an empty patch of the bar around the center and drag it toward another screen edge, and the bar moves there — left, right, top, or bottom all work, and every widget adapts (vertical bars fall back to compact icon-only forms). A click-and-hold starts the same drag. Double-left-click that same empty space to toggle transparency. And drag any widget to reorder it or throw it into another section.
|
||||
Grab an empty patch of the bar around the center and drag it toward another screen edge, and the bar moves there — left, right, top, or bottom all work, and every widget adapts (vertical bars fall back to compact icon-only forms). A click-and-hold starts the same drag. Double-left-click that same empty space to cycle the bar background from clear to glassy to opaque. And drag any widget to reorder it or throw it into another section.
|
||||
|
||||
If you'd rather pick from a menu, **Style → Menu Bar** has both position and transparency.
|
||||
If you'd rather pick from a menu, **Trigger → Appearance → Menu Bar** has the position, and **Bar Background** picks how the bar is drawn: **Opaque Bar**, **Glassy Bar** (see-through, with what's behind it blurred), or **Clear Bar**.
|
||||
|
||||
The same things have commands, which is what you want for a [dotfiles](31-dotfiles.md) setup:
|
||||
|
||||
```bash
|
||||
omarchy bar position bottom
|
||||
omarchy bar transparent toggle
|
||||
omarchy bar background glassy # opaque, glassy, none, or cycle
|
||||
omarchy bar move omarchy.clock --section center --index 0
|
||||
omarchy bar set omarchy.clock format "HH:mm"
|
||||
omarchy bar defaults # back to the shipped layout
|
||||
@@ -104,7 +104,7 @@ omarchy plugin disable omarchy.weather
|
||||
|
||||
## Hiding the bar
|
||||
|
||||
`Super + Shift + Space` toggles the bar off and back on without killing the shell — panels and hotkeys keep working, you just get the pixels back. It's also in the menu under **Trigger → Toggle → Menu Bar**.
|
||||
`Super + Shift + Space` toggles the bar off and back on without killing the shell — panels and hotkeys keep working, you just get the pixels back. It's also in the menu under **Trigger → Appearance → Menu Bar → Hide Bar**.
|
||||
|
||||
## The config file
|
||||
|
||||
@@ -115,7 +115,7 @@ All of it is stored in `~/.config/omarchy/shell.json`, under the `bar` key. Here
|
||||
"version": 1,
|
||||
"bar": {
|
||||
"position": "top",
|
||||
"transparent": false,
|
||||
"background": "opaque",
|
||||
"centerAnchor": "omarchy.clock",
|
||||
"layout": {
|
||||
"left": [{ "id": "omarchy.menu" }, { "id": "omarchy.workspaces" }],
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
echo "Keep windows opaque where animations are turned off"
|
||||
|
||||
# Turning animations off used to make windows opaque too. It no longer touches
|
||||
# transparency, so drop that rule from the saved flag, where it would keep
|
||||
# windows opaque whatever Appearance > Window Transparency says, and carry it
|
||||
# over as Window Transparency > Opaque for anyone who has not picked one yet.
|
||||
# omarchy-hyprland-toggle saved flags under ~/.local/state whatever
|
||||
# XDG_STATE_HOME said, while Hyprland reads them from XDG_STATE_HOME, so both
|
||||
# are fixed.
|
||||
for state_home in "$HOME/.local/state" "${XDG_STATE_HOME:-}"; do
|
||||
[[ -n $state_home ]] || continue
|
||||
toggles_dir="$state_home/omarchy/toggles/hypr"
|
||||
[[ -f $toggles_dir/no-animations.lua ]] || continue
|
||||
|
||||
sed -i '/^o\.window("\.\*", { opacity = "1 1" })$/d' "$toggles_dir/no-animations.lua"
|
||||
|
||||
if [[ ! -f $toggles_dir/window-opaque.lua && ! -f $toggles_dir/window-glassy.lua ]]; then
|
||||
cp "$OMARCHY_PATH/default/hypr/toggles/window-opaque.lua" "$toggles_dir/"
|
||||
fi
|
||||
done
|
||||
+26
-14
@@ -45,7 +45,7 @@ Item {
|
||||
property string omarchyConfigDir: home + "/.config/omarchy"
|
||||
property var fallbackBarConfig: ({
|
||||
position: "top",
|
||||
transparent: false,
|
||||
background: "opaque",
|
||||
centerAnchor: "omarchy.clock",
|
||||
layout: { left: [], center: [], right: [] }
|
||||
})
|
||||
@@ -54,6 +54,12 @@ Item {
|
||||
property bool requestedTransparent: false
|
||||
property bool useTransparentForeground: false
|
||||
property bool transparent: false
|
||||
// A see-through bar that Hyprland blurs behind (the bar-glassy toggle), so
|
||||
// its theme background stays faintly. A transparent bar wins over it.
|
||||
property bool glassy: false
|
||||
// The look the blur behind the bar was last synced for. A background set by
|
||||
// editing shell.json skips the CLI, so the bar syncs Hyprland's blur itself.
|
||||
property string glassSyncedLook: ""
|
||||
property bool centerSectionHovered: false
|
||||
// One bar surface exists per monitor and each reports into this count, so a
|
||||
// pointer crossing from one monitor's bar to another's stays counted however
|
||||
@@ -79,6 +85,7 @@ Item {
|
||||
property color barForeground: useTransparentForeground ? transparentForeground : themeForeground
|
||||
property bool foregroundAnimationEnabled: true
|
||||
property color background: Commons.Color.bar.background
|
||||
readonly property color glassBackground: Qt.rgba(background.r, background.g, background.b, Math.min(background.a, 0.35))
|
||||
property color urgent: Commons.Color.bar.active
|
||||
|
||||
Behavior on barForeground { enabled: root.foregroundAnimationEnabled; ColorAnimation { duration: Style.duration(420); easing.type: Easing.OutCubic } }
|
||||
@@ -651,7 +658,18 @@ Item {
|
||||
var config = Util.isPlainObject(barConfig) ? barConfig : fallbackBarConfig
|
||||
|
||||
position = normalizePosition(config.position)
|
||||
setRequestedTransparency(config.transparent === true)
|
||||
// opaque, glassy or none; a config from before background says
|
||||
// transparent instead.
|
||||
var look = config.background || (config.transparent === true ? "none" : "opaque")
|
||||
setRequestedTransparency(look === "none")
|
||||
// A bar going clear waits for its text color before dropping its
|
||||
// background, so a glassy one stays glassy until then rather than
|
||||
// flashing opaque. Once clear, transparent wins over a stale glassy.
|
||||
if (look !== "none") glassy = look === "glassy"
|
||||
if (look !== glassSyncedLook) {
|
||||
glassSyncedLook = look
|
||||
Util.execDetached("omarchy-bar sync-glass")
|
||||
}
|
||||
centerAnchor = Util.canonicalWidgetId(config.centerAnchor || "")
|
||||
|
||||
// layoutEntries feeds plain JS arrays to the module Repeaters, and QML
|
||||
@@ -913,16 +931,10 @@ Item {
|
||||
Util.execDetached(command)
|
||||
}
|
||||
|
||||
function toggleTransparency() {
|
||||
var nextTransparent = !(root.requestedTransparent === true)
|
||||
if (root.shell && typeof root.shell.mutateShellConfig === "function") {
|
||||
root.shell.mutateShellConfig(function(config) {
|
||||
if (!Util.isPlainObject(config.bar)) config.bar = {}
|
||||
config.bar.transparent = nextTransparent
|
||||
})
|
||||
} else {
|
||||
root.setRequestedTransparency(nextTransparent)
|
||||
}
|
||||
// Steps the bar background from clear to glassy to opaque and around. Through
|
||||
// omarchy-bar, which keeps Hyprland's blur behind a glassy bar in step.
|
||||
function cycleBackground() {
|
||||
Util.execDetached("omarchy-bar background cycle")
|
||||
}
|
||||
|
||||
function rawLayoutSection(config, region) {
|
||||
@@ -1357,7 +1369,7 @@ Item {
|
||||
|
||||
implicitWidth: root.vertical ? thickness : 0
|
||||
implicitHeight: root.vertical ? 0 : thickness
|
||||
color: root.transparent ? "transparent" : root.background
|
||||
color: root.transparent ? "transparent" : (root.glassy ? root.glassBackground : root.background)
|
||||
surfaceFormat.opaque: false
|
||||
WlrLayershell.namespace: "omarchy-bar"
|
||||
WlrLayershell.layer: WlrLayer.Top
|
||||
@@ -1832,7 +1844,7 @@ Item {
|
||||
return
|
||||
}
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
root.toggleTransparency()
|
||||
root.cycleBackground()
|
||||
mouse.accepted = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ the shell for its whole session.
|
||||
|
||||
The bar config lives under the `bar:` key of [`~/.config/omarchy/shell.json`](../../../docs/omarchy-shell.md#shelljson). Out of the box the shell uses [`config/omarchy/shell.json`](../../../config/omarchy/shell.json). Once you customize anything via the bar gestures, `omarchy bar ...`, or by editing shell.json directly, your file is canonical — there is no deep-merge.
|
||||
|
||||
The bar is configured directly on the bar itself: drag empty bar space (or click-and-hold) to move the bar to another screen edge, double-left-click empty center-bar space to toggle transparency, and drag widgets to reorder them. The `omarchy bar position`, `omarchy bar transparent`, `omarchy bar move`, and `omarchy bar set` commands do the same from scripts. Enable or disable widgets with `omarchy plugin enable` and `omarchy plugin disable` (widget ids come from `omarchy plugin list`).
|
||||
The bar is configured directly on the bar itself: drag empty bar space (or click-and-hold) to move the bar to another screen edge, double-left-click empty center-bar space to cycle the bar background from clear to glassy to opaque, and drag widgets to reorder them. The `omarchy bar position`, `omarchy bar background`, `omarchy bar move`, and `omarchy bar set` commands do the same from scripts. Enable or disable widgets with `omarchy plugin enable` and `omarchy plugin disable` (widget ids come from `omarchy plugin list`).
|
||||
|
||||
Example `shell.json` (bar subtree only shown):
|
||||
|
||||
@@ -25,7 +25,7 @@ Example `shell.json` (bar subtree only shown):
|
||||
"version": 1,
|
||||
"bar": {
|
||||
"position": "top",
|
||||
"transparent": false,
|
||||
"background": "opaque",
|
||||
"centerAnchor": "omarchy.clock",
|
||||
"layout": {
|
||||
"left": [
|
||||
|
||||
@@ -393,6 +393,7 @@ function displayRow(items, itemOrder, checkedResults, disabledResults, entry, de
|
||||
// cached while one expression runs lives in that subshell only, so a lazy
|
||||
// memo never survives to the expression after it.
|
||||
var GUARD_READERS = [
|
||||
"omarchy-bar background",
|
||||
"omarchy-bar get omarchy.clock format",
|
||||
"omarchy-bar get omarchy.clock verticalFormat",
|
||||
"omarchy-bar position",
|
||||
@@ -404,6 +405,7 @@ var GUARD_READERS = [
|
||||
"omarchy-default-dictation",
|
||||
"omarchy-dns",
|
||||
"omarchy-hyprland-corners",
|
||||
"omarchy-hyprland-window-transparency",
|
||||
"omarchy-hyprland-workspace-layout-default"
|
||||
]
|
||||
|
||||
|
||||
+5
-3
@@ -47,7 +47,7 @@ ShellRoot {
|
||||
},
|
||||
bar: {
|
||||
position: "top",
|
||||
transparent: false,
|
||||
background: "opaque",
|
||||
centerAnchor: "omarchy.clock",
|
||||
layout: {
|
||||
left: [{ id: "omarchy.menu" }, { id: "omarchy.workspaces" }],
|
||||
@@ -1794,9 +1794,11 @@ ShellRoot {
|
||||
return "ok"
|
||||
}
|
||||
|
||||
// Named for the two-state toggle it once was; it now cycles the bar
|
||||
// background from clear to glassy to opaque and around.
|
||||
function toggleBarTransparency(): string {
|
||||
if (shell.bar && typeof shell.bar.toggleTransparency === "function") {
|
||||
shell.bar.toggleTransparency()
|
||||
if (shell.bar && typeof shell.bar.cycleBackground === "function") {
|
||||
shell.bar.cycleBackground()
|
||||
return "ok"
|
||||
}
|
||||
return "no-bar"
|
||||
|
||||
@@ -59,7 +59,7 @@ const bar = requireFromRoot('shell/plugins/bar/BarModel.js')
|
||||
const barSource = fs.readFileSync(root + '/shell/plugins/bar/Bar.qml', 'utf8')
|
||||
const shellSource = fs.readFileSync(root + '/shell/shell.qml', 'utf8')
|
||||
|
||||
assert(/function toggleBarTransparency\(\): string \{[\s\S]*?shell\.bar\.toggleTransparency\(\)/.test(shellSource), 'shell exposes the bar transparency toggle over IPC')
|
||||
assert(/function toggleBarTransparency\(\): string \{[\s\S]*?shell\.bar\.cycleBackground\(\)/.test(shellSource), 'shell exposes the bar background cycle over IPC')
|
||||
|
||||
// put tolerates a placement target the bar does not carry, so the IPC call
|
||||
// must reach the registry's put rather than route back through enable.
|
||||
|
||||
@@ -255,6 +255,9 @@ pass "Hyprland bootstrap reloads cached Omarchy config modules"
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
mkdir -p "$TMPDIR/home/.config/omarchy"
|
||||
# The bar keeps its blur toggle where Hyprland reads it, under XDG_STATE_HOME,
|
||||
# so that points into the test home too.
|
||||
export XDG_STATE_HOME="$TMPDIR/home/.local/state"
|
||||
|
||||
ipc_mock_bin="$TMPDIR/ipc-mock"
|
||||
mkdir -p "$ipc_mock_bin"
|
||||
@@ -335,16 +338,97 @@ pass "shell config sets bar position"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar transparent true
|
||||
jq -e '
|
||||
.bar.transparent == true and
|
||||
.bar.background == "none" and
|
||||
.bar.position == "bottom" and
|
||||
.plugins == []
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config sets bar transparency"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar transparent toggle
|
||||
jq -e '.bar.transparent == false' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
jq -e '.bar.background == "opaque"' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "shell config toggles bar transparency"
|
||||
|
||||
# The bar background is opaque, glassy or none. A glassy bar needs Hyprland's
|
||||
# blur, so the bar-glassy toggle follows it.
|
||||
printf '#!/bin/bash\nprintf "%%s\\n" "$*" >>"%s/hyprctl.log"\n' "$TMPDIR" >"$ipc_mock_bin/hyprctl"
|
||||
chmod +x "$ipc_mock_bin/hyprctl"
|
||||
glass_toggle="$TMPDIR/home/.local/state/omarchy/toggles/hypr/bar-glassy.lua"
|
||||
bar_background() { HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar background "$@"; }
|
||||
|
||||
bar_background opaque >/dev/null
|
||||
[[ $(bar_background) == "opaque" ]] || fail "an opaque bar background is reported"
|
||||
bar_background glassy >/dev/null
|
||||
jq -e '.bar.background == "glassy"' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null ||
|
||||
fail "shell config sets a glassy bar"
|
||||
[[ $(bar_background) == "glassy" ]] || fail "a glassy bar background is reported"
|
||||
[[ -f $glass_toggle ]] || fail "a glassy bar turns on Hyprland's blur behind it"
|
||||
grep -qx 'reload' "$TMPDIR/hyprctl.log" || fail "a glassy bar reloads Hyprland"
|
||||
bar_background none >/dev/null
|
||||
jq -e '.bar.background == "none"' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null ||
|
||||
fail "a bar without a background is stored as none"
|
||||
[[ ! -f $glass_toggle ]] || fail "a bar without a background turns Hyprland's blur off again"
|
||||
pass "shell config sets the bar background, and Hyprland's blur follows a glassy one"
|
||||
|
||||
seen=()
|
||||
for _ in 1 2 3; do
|
||||
bar_background cycle >/dev/null
|
||||
seen+=("$(bar_background)")
|
||||
done
|
||||
[[ ${seen[*]} == "glassy opaque none" ]] || fail "the bar background cycles from clear to glassy to opaque and around" "${seen[*]}"
|
||||
if bar_background frosted 2>/dev/null; then
|
||||
fail "an unknown bar background is refused"
|
||||
fi
|
||||
: >"$TMPDIR/hyprctl.log"
|
||||
bar_background opaque >/dev/null
|
||||
[[ ! -s $TMPDIR/hyprctl.log ]] || fail "Hyprland reloads only when the bar's glass changes"
|
||||
pass "the bar background cycles through its looks and refuses unknown ones"
|
||||
|
||||
# transparent stays for scripts written against it: true is none, false opaque.
|
||||
bar_background glassy >/dev/null
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar transparent true >/dev/null
|
||||
[[ $(bar_background) == "none" ]] || fail "transparent true leaves the bar without a background"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar transparent toggle >/dev/null
|
||||
[[ $(bar_background) == "opaque" ]] || fail "toggling transparency off makes the bar opaque"
|
||||
# A shell.json from before background says transparent, which reads as none
|
||||
# and is dropped once a background is set.
|
||||
jq '.bar.transparent = true | del(.bar.background)' "$TMPDIR/home/.config/omarchy/shell.json" >"$TMPDIR/legacy.json" &&
|
||||
mv "$TMPDIR/legacy.json" "$TMPDIR/home/.config/omarchy/shell.json"
|
||||
[[ $(bar_background) == "none" ]] || fail "an older transparent bar reads as no background"
|
||||
bar_background glassy >/dev/null
|
||||
jq -e '.bar.background == "glassy" and (.bar | has("transparent") | not)' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null ||
|
||||
fail "setting a background drops the older transparent flag"
|
||||
pass "the older transparent form still sets and reads as the bar background"
|
||||
|
||||
# Restoring the default bar also restores its opaque background, and the blur
|
||||
# behind a glassy one goes with it.
|
||||
bar_background glassy >/dev/null
|
||||
[[ -f $glass_toggle ]] || fail "a glassy bar has its blur on before defaults"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar defaults >/dev/null
|
||||
[[ $(bar_background) == "opaque" && ! -f $glass_toggle ]] || fail "omarchy bar defaults turns a glassy bar's blur off"
|
||||
pass "restoring the default bar turns a glassy bar's blur off"
|
||||
|
||||
# A background set by editing shell.json gets its blur when the shell syncs it.
|
||||
jq '.bar.background = "glassy"' "$TMPDIR/home/.config/omarchy/shell.json" >"$TMPDIR/edited.json" &&
|
||||
mv "$TMPDIR/edited.json" "$TMPDIR/home/.config/omarchy/shell.json"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar sync-glass
|
||||
[[ -f $glass_toggle ]] || fail "syncing a hand-edited glassy bar turns its blur on"
|
||||
jq '.bar.background = "opaque"' "$TMPDIR/home/.config/omarchy/shell.json" >"$TMPDIR/edited.json" &&
|
||||
mv "$TMPDIR/edited.json" "$TMPDIR/home/.config/omarchy/shell.json"
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar sync-glass
|
||||
[[ ! -f $glass_toggle ]] || fail "syncing a hand-edited opaque bar turns its blur off"
|
||||
pass "a bar background edited into shell.json gets its blur synced"
|
||||
|
||||
# A glassy bar whose blur can't be turned on keeps the background it had.
|
||||
toggles_dir="${glass_toggle%/*}"
|
||||
chmod a-w "$toggles_dir"
|
||||
if bar_background glassy >/dev/null 2>&1; then
|
||||
chmod u+w "$toggles_dir"
|
||||
fail "a bar whose blur can't be turned on reports failure"
|
||||
fi
|
||||
chmod u+w "$toggles_dir"
|
||||
[[ $(bar_background) == "opaque" && ! -f $glass_toggle ]] || fail "a bar whose blur can't be turned on keeps its old background" "$(bar_background)"
|
||||
pass "a bar whose blur can't change keeps its old background"
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-bar set omarchy.bluetooth enabled false --json
|
||||
grep -Fqx 'shell setBarWidget omarchy.bluetooth enabled false {}' \
|
||||
"$TMPDIR/home/.local/state/omarchy/shell-ipc-calls"
|
||||
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
trap 'rm -rf "$tmpdir"' EXIT
|
||||
|
||||
stub_dir="$tmpdir/bin"
|
||||
home_dir="$tmpdir/home"
|
||||
state_home="$tmpdir/state"
|
||||
toggles_dir="$state_home/omarchy/toggles/hypr"
|
||||
mkdir -p "$stub_dir" "$home_dir"
|
||||
|
||||
for command in hyprctl omarchy-notification-send omarchy-restart-terminal omarchy-theme-set-foot omarchy-restart-btop; do
|
||||
printf '#!/bin/bash\nprintf "%%s\\n" "%s $*" >>"%s/commands.log"\n' "$command" "$tmpdir" >"$stub_dir/$command"
|
||||
done
|
||||
chmod +x "$stub_dir"/*
|
||||
|
||||
run() {
|
||||
HOME="$home_dir" XDG_RUNTIME_DIR="$tmpdir" XDG_STATE_HOME="$state_home" XDG_CONFIG_HOME="$home_dir/.config" OMARCHY_PATH="$ROOT" PATH="$stub_dir:$ROOT/bin:$PATH" "$@"
|
||||
}
|
||||
|
||||
[[ $(run omarchy-hyprland-window-transparency) == "transparent" ]] || fail "windows start out transparent"
|
||||
pass "windows start out transparent"
|
||||
|
||||
run omarchy-hyprland-window-transparency glassy
|
||||
[[ $(run omarchy-hyprland-window-transparency) == "glassy" ]] || fail "glassy windows are reported"
|
||||
cmp -s "$ROOT/default/hypr/toggles/window-glassy.lua" "$toggles_dir/window-glassy.lua" || fail "glassy windows are loaded after the theme"
|
||||
grep -qx 'hyprctl reload' "$tmpdir/commands.log" || fail "new transparency reloads Hyprland"
|
||||
grep -q '^omarchy-restart-btop ' "$tmpdir/commands.log" || fail "new transparency reloads running btop windows"
|
||||
pass "glassy windows override the theme"
|
||||
|
||||
run omarchy-hyprland-window-transparency opaque
|
||||
[[ $(run omarchy-hyprland-window-transparency) == "opaque" ]] || fail "opaque windows are reported"
|
||||
[[ ! -e $toggles_dir/window-glassy.lua ]] || fail "opaque windows replace glassy ones"
|
||||
pass "opaque windows replace glassy ones"
|
||||
|
||||
run omarchy-hyprland-window-transparency transparent
|
||||
[[ $(run omarchy-hyprland-window-transparency) == "transparent" ]] || fail "transparent windows are reported"
|
||||
[[ ! -e $toggles_dir/window-opaque.lua ]] || fail "transparent windows drop the override"
|
||||
pass "transparent windows drop the override"
|
||||
|
||||
if run omarchy-hyprland-window-transparency frosted 2>/dev/null; then
|
||||
fail "unknown transparency is refused"
|
||||
fi
|
||||
pass "unknown transparency is refused"
|
||||
|
||||
# A failed save keeps the transparency already chosen.
|
||||
run omarchy-hyprland-window-transparency glassy
|
||||
chmod a-w "$toggles_dir"
|
||||
if run omarchy-hyprland-window-transparency opaque 2>/dev/null; then
|
||||
chmod u+w "$toggles_dir"
|
||||
fail "a failed save is reported"
|
||||
fi
|
||||
chmod u+w "$toggles_dir"
|
||||
[[ $(run omarchy-hyprland-window-transparency) == "glassy" ]] || fail "a failed save keeps the transparency already chosen"
|
||||
run omarchy-hyprland-window-transparency transparent
|
||||
pass "a failed save keeps the transparency already chosen"
|
||||
|
||||
# GTK apps only ask Hyprland for blur under a CSS backdrop-filter, so glassy
|
||||
# imports one into the user's gtk.css, leaving the rest of it alone.
|
||||
gtk_css="$home_dir/.config/gtk-4.0/gtk.css"
|
||||
mkdir -p "${gtk_css%/*}"
|
||||
printf 'label { color: red; }\n' >"$gtk_css"
|
||||
run omarchy-hyprland-window-transparency glassy
|
||||
grep -qxF "@import url(\"file://$ROOT/default/gtk/glass.css\");" "$gtk_css" || fail "glassy GTK apps import the backdrop blur"
|
||||
grep -qx 'label { color: red; }' "$gtk_css" || fail "glassy keeps the user's own GTK CSS"
|
||||
run omarchy-hyprland-window-transparency glassy
|
||||
(( $(grep -c 'omarchy-glass begin' "$gtk_css") == 1 )) || fail "glassy GTK apps import the backdrop blur once"
|
||||
run omarchy-hyprland-window-transparency transparent
|
||||
[[ $(<"$gtk_css") == 'label { color: red; }' ]] || fail "leaving glassy restores the user's GTK CSS"
|
||||
grep -qF 'backdrop-filter: blur(' "$ROOT/default/gtk/glass.css" || fail "the GTK glass is a backdrop blur"
|
||||
printf 'label { color: red; }' >"$gtk_css"
|
||||
run omarchy-hyprland-window-transparency glassy
|
||||
run omarchy-hyprland-window-transparency transparent
|
||||
[[ $(od -An -c "$gtk_css" | tr -d ' \n') == 'label{color:red;}' ]] || fail "leaving glassy restores GTK CSS without a final newline"
|
||||
|
||||
# A GTK config that cannot be written fails the change rather than announcing it.
|
||||
printf 'label { color: red; }\n' >"$gtk_css"
|
||||
chmod a-w "$gtk_css"
|
||||
: >"$tmpdir/commands.log"
|
||||
if run omarchy-hyprland-window-transparency glassy 2>/dev/null; then
|
||||
chmod u+w "$gtk_css"
|
||||
fail "a GTK config that cannot be written fails the change"
|
||||
fi
|
||||
chmod u+w "$gtk_css"
|
||||
! grep -q '^omarchy-notification-send' "$tmpdir/commands.log" || fail "a failed change is not announced"
|
||||
[[ $(run omarchy-hyprland-window-transparency) == "transparent" ]] || fail "a failed change keeps the previous choice"
|
||||
run omarchy-hyprland-window-transparency transparent
|
||||
pass "glassy GTK apps get a backdrop blur, and leaving glassy takes it out"
|
||||
|
||||
# Opaque reaches the windows Omarchy makes transparent through their tag.
|
||||
grep -qF 'tag = "+transparent-window"' "$ROOT/default/hypr/helpers.lua" || fail "transparent windows carry a tag"
|
||||
grep -qF 'o.window({ tag = "transparent-window" }, { opacity = "1 1" })' "$ROOT/default/hypr/toggles/window-opaque.lua" ||
|
||||
fail "opaque windows apply to the tagged windows"
|
||||
pass "opaque windows apply to the windows Omarchy makes transparent"
|
||||
|
||||
# Terminals turn compositor blur down and fade their text with the window, so
|
||||
# glassy gives each theme terminal file a see-through, blurred background.
|
||||
theme_dir="$tmpdir/theme"
|
||||
mkdir -p "$theme_dir"
|
||||
printf '[colors.primary]\nbackground = "#000000"\n' >"$theme_dir/alacritty.toml"
|
||||
printf '[colors-dark]\nbackground=000000\n' >"$theme_dir/foot.ini"
|
||||
printf 'background #000000\n' >"$theme_dir/kitty.conf"
|
||||
printf 'background = #000000\nbackground-opacity = 0.9\n' >"$theme_dir/ghostty.conf"
|
||||
printf 'theme[main_bg]="#102030"\ntheme[main_fg]="#ffffff"\n' >"$theme_dir/btop.theme"
|
||||
cp -r "$theme_dir" "$tmpdir/theme-before"
|
||||
|
||||
run omarchy-hyprland-window-transparency glassy
|
||||
run omarchy-theme-set-glass "$theme_dir"
|
||||
run omarchy-theme-set-glass "$theme_dir"
|
||||
grep -qx 'opacity = 0.65' "$theme_dir/alacritty.toml" || fail "glassy alacritty is see-through"
|
||||
grep -qx 'alpha=0.65' "$theme_dir/foot.ini" && grep -qx 'blur=yes' "$theme_dir/foot.ini" || fail "glassy foot is see-through and asks for blur"
|
||||
grep -qx 'background_opacity 0.65' "$theme_dir/kitty.conf" || fail "glassy kitty is see-through"
|
||||
(( $(grep -c 'omarchy-glass begin' "$theme_dir/foot.ini") == 1 )) || fail "glassy terminals get the glass once"
|
||||
[[ $(grep '^theme\[main_bg\]=' "$theme_dir/btop.theme" | tail -1) == 'theme[main_bg]=""' ]] || fail "glassy btop uses the terminal background"
|
||||
(( $(grep -c 'omarchy-glass begin' "$theme_dir/btop.theme") == 1 )) || fail "glassy btop gets the glass once"
|
||||
pass "btop follows the glassy terminal background"
|
||||
(( $(grep -c 'background-opacity' "$theme_dir/ghostty.conf") == 1 )) &&
|
||||
grep -qx 'background-opacity = 0.9' "$theme_dir/ghostty.conf" || fail "a theme's own terminal opacity is kept"
|
||||
grep -qx "gtk-custom-css = $ROOT/default/gtk/glass.css" "$theme_dir/ghostty.conf" ||
|
||||
fail "a ghostty theme with its own opacity still gets the backdrop blur"
|
||||
# A foot theme with its own alpha keeps it but still asks for blur, as
|
||||
# Hyprland skips blur for foot unless it does.
|
||||
own_alpha_dir="$tmpdir/own-alpha-theme"
|
||||
mkdir -p "$own_alpha_dir"
|
||||
printf '[colors-dark]\nbackground=000000\nalpha=0.8\n' >"$own_alpha_dir/foot.ini"
|
||||
run omarchy-theme-set-glass "$own_alpha_dir"
|
||||
(( $(grep -c '^alpha=' "$own_alpha_dir/foot.ini") == 1 )) && grep -qx 'alpha=0.8' "$own_alpha_dir/foot.ini" &&
|
||||
grep -qx 'blur=yes' "$own_alpha_dir/foot.ini" || fail "a foot theme with its own alpha still asks for blur"
|
||||
if command -v foot >/dev/null; then
|
||||
foot --check-config -c "$own_alpha_dir/foot.ini" || fail "a foot theme with its own alpha stays valid"
|
||||
fi
|
||||
pass "a theme's own terminal opacity is kept, and its blur is still added"
|
||||
if command -v foot >/dev/null; then
|
||||
foot --check-config -c "$theme_dir/foot.ini" || fail "glassy foot config is valid"
|
||||
fi
|
||||
# A window table of the theme's own takes the glass in, as TOML refuses a
|
||||
# table declared twice.
|
||||
window_dir="$tmpdir/window-theme"
|
||||
mkdir -p "$window_dir"
|
||||
printf '[window] # mine\npadding = { x = 4, y = 4 }\nblur = false\n\n[colors.primary]\nbackground = "#000000"\n' >"$window_dir/alacritty.toml"
|
||||
cp "$window_dir/alacritty.toml" "$tmpdir/window-before.toml"
|
||||
run omarchy-theme-set-glass "$window_dir"
|
||||
run omarchy-theme-set-glass "$window_dir"
|
||||
(( $(grep -c '^\[window\]' "$window_dir/alacritty.toml") == 1 )) || fail "glassy alacritty keeps a single window table"
|
||||
if command -v python3 >/dev/null; then
|
||||
python3 -c 'import sys, tomllib; c = tomllib.load(open(sys.argv[1], "rb")); assert c["window"]["opacity"] == 0.65 and c["window"]["padding"]["x"] == 4' "$window_dir/alacritty.toml" ||
|
||||
fail "glassy alacritty with a window table of its own stays valid TOML"
|
||||
fi
|
||||
HOME="$home_dir" XDG_STATE_HOME="$tmpdir/no-glass" OMARCHY_PATH="$ROOT" PATH="$stub_dir:$ROOT/bin:$PATH" omarchy-theme-set-glass "$window_dir"
|
||||
cmp -s "$tmpdir/window-before.toml" "$window_dir/alacritty.toml" || fail "leaving glassy restores an alacritty window table"
|
||||
pass "glassy alacritty joins a window table the theme already has"
|
||||
|
||||
# A file without a final newline gets one with the glass, and loses it again
|
||||
# when the glass comes out, so leaving glassy restores it byte for byte.
|
||||
bare_dir="$tmpdir/bare-theme"
|
||||
mkdir -p "$bare_dir"
|
||||
printf 'background #000000' >"$bare_dir/kitty.conf"
|
||||
cp "$bare_dir/kitty.conf" "$tmpdir/bare-before.conf"
|
||||
run omarchy-theme-set-glass "$bare_dir"
|
||||
grep -qx 'background_opacity 0.65' "$bare_dir/kitty.conf" || fail "glassy reaches a file without a final newline"
|
||||
grep -qx 'background #000000' "$bare_dir/kitty.conf" || fail "glassy ends the line before its block"
|
||||
HOME="$home_dir" XDG_STATE_HOME="$tmpdir/no-glass" OMARCHY_PATH="$ROOT" PATH="$stub_dir:$ROOT/bin:$PATH" omarchy-theme-set-glass "$bare_dir"
|
||||
cmp -s "$tmpdir/bare-before.conf" "$bare_dir/kitty.conf" || fail "leaving glassy restores a file without a final newline"
|
||||
pass "leaving glassy restores a file without a final newline byte for byte"
|
||||
|
||||
btop_dir="$tmpdir/transparent-btop-theme"
|
||||
mkdir -p "$btop_dir"
|
||||
printf 'theme[main_bg]=""\n' >"$btop_dir/btop.theme"
|
||||
cp "$btop_dir/btop.theme" "$tmpdir/btop-before.theme"
|
||||
run omarchy-theme-set-glass "$btop_dir"
|
||||
cmp -s "$tmpdir/btop-before.theme" "$btop_dir/btop.theme" || fail "btop themes already using the terminal background are kept"
|
||||
pass "btop themes already using the terminal background are kept"
|
||||
|
||||
ghostty_dir="$tmpdir/ghostty-theme"
|
||||
mkdir -p "$ghostty_dir"
|
||||
printf 'background = #000000\n' >"$ghostty_dir/ghostty.conf"
|
||||
run omarchy-theme-set-glass "$ghostty_dir"
|
||||
grep -qx 'background-opacity = 0.65' "$ghostty_dir/ghostty.conf" &&
|
||||
grep -qx "gtk-custom-css = $ROOT/default/gtk/glass.css" "$ghostty_dir/ghostty.conf" ||
|
||||
fail "glassy ghostty is see-through and loads the GTK backdrop blur"
|
||||
pass "glassy terminals get a see-through, blurred background"
|
||||
|
||||
run omarchy-hyprland-window-transparency transparent
|
||||
run omarchy-theme-set-glass "$theme_dir"
|
||||
diff -r "$tmpdir/theme-before" "$theme_dir" || fail "leaving glassy restores the terminal files"
|
||||
pass "leaving glassy restores the terminal files"
|
||||
|
||||
# Running foot terminals take the theme's background alpha over OSC, so a
|
||||
# change of transparency reaches them without a restart. script stands in for
|
||||
# foot: its child sits on a real pty, and whatever reaches the pty lands in the
|
||||
# typescript.
|
||||
if command -v script >/dev/null; then
|
||||
foot_home="$tmpdir/foot-home"
|
||||
foot_theme="$foot_home/.local/state/omarchy/current/theme"
|
||||
mkdir -p "$foot_theme" "$tmpdir/foot-bin"
|
||||
printf 'background = "#102030"\nforeground = "#ffffff"\n' >"$foot_theme/colors.toml"
|
||||
printf '[colors-dark]\nbackground=102030\n' >"$foot_theme/foot.ini"
|
||||
|
||||
script -qfc "sleep 30" "$tmpdir/typescript" >/dev/null 2>&1 &
|
||||
script_pid=$!
|
||||
for _ in {1..50}; do pgrep -P "$script_pid" >/dev/null && break; sleep 0.1; done
|
||||
|
||||
# Only the foot lookup is faked; finding its shell goes to the real pgrep.
|
||||
real_pgrep=$(command -v pgrep)
|
||||
printf '#!/bin/bash\nif [[ $1 == "-x" && $2 == "foot" ]]; then echo %s; else exec %s "$@"; fi\n' "$script_pid" "$real_pgrep" >"$tmpdir/foot-bin/pgrep"
|
||||
chmod +x "$tmpdir/foot-bin/pgrep"
|
||||
|
||||
set_foot() {
|
||||
HOME="$foot_home" PATH="$tmpdir/foot-bin:$ROOT/bin:$PATH" omarchy-theme-set-foot
|
||||
sleep 0.3
|
||||
}
|
||||
|
||||
set_foot
|
||||
grep -qF $'\e]11;[100]#102030' "$tmpdir/typescript" || fail "running foot terminals stay opaque without glass"
|
||||
printf '# omarchy-glass begin\n[colors-dark]\nalpha=0.65\nblur=yes\n# omarchy-glass end\n' >>"$foot_theme/foot.ini"
|
||||
set_foot
|
||||
grep -qF $'\e]11;[65]#102030' "$tmpdir/typescript" || fail "running foot terminals turn glassy"
|
||||
kill "$script_pid" 2>/dev/null || true
|
||||
pass "running foot terminals take the theme's background alpha"
|
||||
else
|
||||
skip "script is not installed"
|
||||
fi
|
||||
|
||||
grep -qx 'blur=yes' "$ROOT/default/themed/foot.ini.tpl" || fail "foot starts ready to blur"
|
||||
grep -qx 'dynamic_background_opacity yes' "$ROOT/default/themed/kitty.conf.tpl" || fail "kitty starts ready to change opacity"
|
||||
pass "foot and kitty start ready for glass, since they read that only at launch"
|
||||
@@ -365,7 +365,7 @@ assert(
|
||||
)
|
||||
assertDeepEqual(
|
||||
defaultItems.filter(item => item.parent === 'trigger.appearance.top-bar').map(item => item.label),
|
||||
['Hide Bar', 'Show Bar', 'Position Bar', 'Transparent Bar', 'Opaque Bar', 'Indicators'],
|
||||
['Hide Bar', 'Show Bar', 'Position Bar', 'Bar Background', 'Bar Indicators'],
|
||||
'menu gathers the Menu Bar under Trigger > Appearance'
|
||||
)
|
||||
assert(
|
||||
@@ -384,16 +384,43 @@ assert(
|
||||
['top', 'bottom', 'left', 'right'].every(position => defaultById[`trigger.appearance.top-bar.position.${position}`].action === `omarchy-bar position ${position}`),
|
||||
'menu lists all Menu Bar positions under Position'
|
||||
)
|
||||
assert(
|
||||
defaultById['trigger.appearance.top-bar.transparent'].action === 'omarchy-bar transparent true'
|
||||
&& defaultById['trigger.appearance.top-bar.opaque'].action === 'omarchy-bar transparent false'
|
||||
&& defaultById['trigger.appearance.top-bar.transparent'].when === '! ' + defaultById['trigger.appearance.top-bar.opaque'].when,
|
||||
'menu offers Transparent Bar while the bar is opaque and Opaque Bar while it is transparent'
|
||||
assertDeepEqual(
|
||||
defaultItems.filter(item => item.parent === 'trigger.appearance.top-bar.background').map(item => [item.label, item.action]),
|
||||
[
|
||||
['Opaque Bar', 'omarchy-bar background opaque'],
|
||||
['Glassy Bar', 'omarchy-bar background glassy'],
|
||||
['Clear Bar', 'omarchy-bar background none']
|
||||
],
|
||||
'menu picks the bar background from Menu Bar > Bar Background'
|
||||
)
|
||||
// Exactly the bar's current background is checked. Ask bash, against a
|
||||
// shell.json in each state, which rows it checks.
|
||||
{
|
||||
const os = require('os')
|
||||
const { execFileSync } = require('child_process')
|
||||
const home = fs.mkdtempSync(path.join(os.tmpdir(), 'menu-bar-background-'))
|
||||
fs.mkdirSync(path.join(home, '.config/omarchy'), { recursive: true })
|
||||
const checked = bar => {
|
||||
fs.writeFileSync(path.join(home, '.config/omarchy/shell.json'), JSON.stringify({ bar }))
|
||||
return ['opaque', 'glassy', 'clear'].filter(look => {
|
||||
try {
|
||||
execFileSync('bash', ['-c', defaultById[`trigger.appearance.top-bar.background.${look}`].checked], { env: { ...process.env, HOME: home, OMARCHY_PATH: root, PATH: `${root}/bin:${process.env.PATH}` } })
|
||||
return true
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
assertDeepEqual(checked({}), ['opaque'], 'menu checks Opaque Bar while the bar is opaque')
|
||||
assertDeepEqual(checked({ background: 'glassy' }), ['glassy'], 'menu checks Glassy Bar while the bar is glassy')
|
||||
assertDeepEqual(checked({ background: 'none' }), ['clear'], 'menu checks Clear Bar while the bar has no background')
|
||||
assertDeepEqual(checked({ transparent: true }), ['clear'], 'menu checks Clear Bar for a bar made transparent before backgrounds')
|
||||
fs.rmSync(home, { recursive: true, force: true })
|
||||
}
|
||||
assertDeepEqual(
|
||||
defaultItems.filter(item => item.parent === 'trigger.appearance.top-bar.indicators').map(item => item.label),
|
||||
['Battery Percentage', 'Clock'],
|
||||
'menu gathers bar indicator options under Menu Bar > Indicators'
|
||||
'menu gathers bar indicator options under Menu Bar > Bar Indicators'
|
||||
)
|
||||
const clockModel = requireFromRoot('shell/plugins/panels/clock/Model.js')
|
||||
const clockRows = defaultItems.filter(item => item.parent === 'trigger.appearance.top-bar.indicators.clock')
|
||||
@@ -417,8 +444,17 @@ assertDeepEqual(
|
||||
[['Theme Corners', 'omarchy-hyprland-corners theme'], ['Sharp Corners', 'omarchy-hyprland-corners sharp'], ['Rounded Corners', 'omarchy-hyprland-corners rounded']],
|
||||
'menu picks window corners from Appearance > Window Corners'
|
||||
)
|
||||
assertDeepEqual(
|
||||
defaultItems.filter(item => item.parent === 'trigger.appearance.window-transparency').map(item => [item.label, item.action]),
|
||||
[
|
||||
['Opaque Windows', 'omarchy-hyprland-window-transparency opaque'],
|
||||
['Transparent Windows', 'omarchy-hyprland-window-transparency transparent'],
|
||||
['Glassy Windows', 'omarchy-hyprland-window-transparency glassy']
|
||||
],
|
||||
'menu picks window transparency from Appearance > Window Transparency'
|
||||
)
|
||||
const triggerIds = triggerItems.map(item => item.id)
|
||||
const appearanceLabels = ['Animations', 'Menu Bar', 'Window Gaps', 'Window Corners', '1-Window Ratio', 'Workspace Layout', 'Herdr Theme Sync']
|
||||
const appearanceLabels = ['Animations', 'Menu Bar', 'Window Gaps', 'Window Corners', 'Window Transparency', '1-Window Ratio', 'Workspace Layout', 'Herdr Theme Sync']
|
||||
assertEqual(triggerIds.indexOf('trigger.toggle'), triggerIds.indexOf('trigger.appearance') + 1, 'menu places Toggle right after Appearance')
|
||||
assertDeepEqual(
|
||||
defaultItems.filter(item => item.parent === 'trigger.appearance').map(item => item.label),
|
||||
|
||||
@@ -41,7 +41,7 @@ printf 'no newline {{ accent }}' >"$themed/tail.txt.tpl"
|
||||
# Function arguments may be separated by any whitespace, tabs included.
|
||||
printf '{{ mix\tbackground accent 30%% }} {{\tmix_rgb red\tblue 50%%\t}} {{ gradient_start\thyprland_active_border accent }}\n' >"$themed/tabs.txt.tpl"
|
||||
|
||||
HOME="$home" OMARCHY_PATH="$ROOT" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-theme-set-templates"
|
||||
HOME="$home" XDG_STATE_HOME="$home/.local/state" OMARCHY_PATH="$ROOT" PATH="$ROOT/bin:$PATH" "$ROOT/bin/omarchy-theme-set-templates"
|
||||
|
||||
# Expected values were produced by the sed-based renderer this replaced, so
|
||||
# every theme keeps rendering byte for byte the same.
|
||||
|
||||
@@ -106,8 +106,30 @@ for virt in vm none; do
|
||||
HOME="$test_home" OMARCHY_PATH="$ROOT" bash "$ROOT/install/user/hardware/vm-no-animations.sh" >/dev/null
|
||||
if [[ $virt == "vm" ]]; then
|
||||
[[ -f $animations_flag ]] || fail "a VM install turns animations off"
|
||||
[[ -f ${animations_flag%/*}/window-opaque.lua ]] || fail "a VM install starts with opaque windows"
|
||||
else
|
||||
[[ ! -f $animations_flag ]] || fail "a machine that is not a VM keeps its animations"
|
||||
[[ ! -f ${animations_flag%/*}/window-opaque.lua ]] || fail "a machine that is not a VM keeps transparent windows"
|
||||
fi
|
||||
done
|
||||
pass "a VM install starts without animations"
|
||||
pass "a VM install starts without animations and with opaque windows"
|
||||
|
||||
# Animations off no longer makes windows opaque. The migration takes that rule
|
||||
# out of a saved flag, keeping anything else in it, and keeps those windows
|
||||
# opaque through Window Transparency instead.
|
||||
migration_home=$(mktemp -d)
|
||||
migration_flags="$migration_home/.local/state/omarchy/toggles/hypr"
|
||||
mkdir -p "$migration_flags"
|
||||
printf 'hl.config({ animations = { enabled = false } })\n\no.window(".*", { opacity = "1 1" })\n-- mine\n' >"$migration_flags/no-animations.lua"
|
||||
for _ in 1 2; do
|
||||
HOME="$migration_home" XDG_STATE_HOME="" OMARCHY_PATH="$ROOT" bash -euo pipefail "$ROOT/migrations/1791705142.sh" >/dev/null
|
||||
done
|
||||
! grep -q 'opacity' "$migration_flags/no-animations.lua" || fail "the migration drops the opacity rule from a saved animations flag"
|
||||
grep -qx -- '-- mine' "$migration_flags/no-animations.lua" || fail "the migration keeps the rest of a saved animations flag"
|
||||
[[ -f $migration_flags/window-opaque.lua ]] || fail "the migration keeps windows opaque where animations are off"
|
||||
rm -f "$migration_flags/window-opaque.lua"
|
||||
printf 'x\n' >"$migration_flags/window-glassy.lua"
|
||||
HOME="$migration_home" XDG_STATE_HOME="" OMARCHY_PATH="$ROOT" bash -euo pipefail "$ROOT/migrations/1791705142.sh" >/dev/null
|
||||
[[ ! -f $migration_flags/window-opaque.lua ]] || fail "the migration leaves a chosen transparency alone"
|
||||
rm -rf "$migration_home"
|
||||
pass "the migration moves opaque windows from the animations flag to Window Transparency"
|
||||
Reference in new issue
Block a user